就在最近,我了解到你可以使用类似函数类型的变量语法来声明一个函数(包括方法):
using function_type = int (double);
// pre-C++11:
//typedef int function_type(double);
function_type fun_global;
struct methods
{
static function_type mem_fun_static;
function_type mem_fun_normal;
virtual function_type mem_fun_virtual;
virtual function_type mem_fun_abstract = 0;
};
在上面的代码中
fun_global
是一个全局函数,mem_fun_static
是static
成员函数,mem_fun_normal
是一种普通的方法,mem_fun_virtual
是virtual
方法,mem_fun_abstract
是一种抽象方法。所有这些都采用double
类型的单个参数并返回int
值 - 就像function_type
所说的那样。
这些年来,我知道C ++并且我不知道这个 - 这种语言永远不会让我感到惊讶!顺便说一下 - 这个语法是在here的任何地方提到的吗?我没有看到这个...
然而,在探索这个新功能时,我偶然发现编译器之间存在一些不一致之处。对于测试,我使用了以下编译器:
g++ -Wall -Wextra -pedantic -std=c++14
clang++ -Wall -Wextra -pedantic -std=c++14
cl /W4 /EHsc
在我运行的测试中,两个GCC版本给出了相同的结果,所以我将它们称为GCC。
= delete
不一致struct methods
{
/* ... */
function_type mem_fun_deleted = delete;
};
Clang:错误!
Test.cpp:13:34: error: '= delete' is a function definition and must occur in a standalone declaration
function_type mem_fun_deleted = delete;
^
1 error generated.
MSVC:好的
= default
不一致struct methods
{
/* ... */
using assignment_type = methods& (methods const&);
assignment_type operator= = default;
};
Clang:错误!
Test.cpp:14:30: error: '= default' is a function definition and must occur in a standalone declaration
assignment_type operator= = default;
^
1 error generated.
MSVC:错误!
Test.cpp(14): error C2206: 'methods::operator =': typedef cannot be used for function definition
struct methods
{
/* ... */
function_type mem_fun_inline { return 0; }
};
海湾合作委员会:错误!
Test.cpp:13:43: error: invalid initializer for member function ‘int methods::mem_fun_inline(double)’
function_type mem_fun_inline { return 0; }
^
Test.cpp:13:43: error: expected ‘;’ at end of member declaration
Clang:错误!
Test.cpp:13:33: error: expected expression
function_type mem_fun_inline { return 0; }
^
Test.cpp:7:8: error: missing '}' at end of definition of 'methods'
struct methods
^
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++config.h:194:1: note: still within definition of 'methods' here
namespace std
^
2 errors generated.
MSVC:好的
哪些编译器就在这里?
此外,是否有可能:
以某种方式使用function_type
来定义这些函数(在类之外完成时)。以下是可以的(使用所有编译器)
struct methods
{
static function_type mem_fun_static;
/* ... */
};
int methods::mem_fun_static(double) { return 0; }
由于function_type
的更改应该导致函数定义中的编译错误(因为它将不再匹配声明),所以并没有那么糟糕 - 但是仍然可以避免这种情况。
答案 0 :(得分:4)
§8.3.5函数[dcl.fct] p12函数类型的typedef可用于声明函数,但不得用于定义函数。
因此Clang在所有情况下拒绝代码是正确的,接受它的编译器是错误的。
(报价来自N4618,但规则是永远的语言的一部分)。