使用函数类型语法声明成员函数
Declaring member function using function type syntax
最近我了解到您可以使用函数类型的类似变量的语法来声明一个函数(包括方法):
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
类型的单个参数和 return int
值 - 正如 function_type
所说。
这么多年我都知道 C++ 而我对此一无所知 - 这种语言总是让我感到惊讶!顺便说一句 - 这种语法在任何地方都提到过 here 吗?我没看到这个...
然而,在探索这个对我来说新的功能时,我偶然发现了编译器之间的一些不一致。对于测试,我使用了以下编译器:
- GCC 5.4.0 和 7.1.0,命令行:
g++ -Wall -Wextra -pedantic -std=c++14
- Clang 4.0.1,命令行:
clang++ -Wall -Wextra -pedantic -std=c++14
- MSVC 19.10.25019 (VS 2017),命令行:
cl /W4 /EHsc
在我 运行 的测试中,两个 GCC 版本都给出了相同的结果,因此我进一步将它们称为 GCC。
= delete
不一致
struct methods
{
/* ... */
function_type mem_fun_deleted = delete;
};
- 海湾合作委员会:好的
当当:错误!
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;
};
- 海湾合作委员会:好的
当当:错误!
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
当当:错误!
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:好的
问题
这里有哪些编译器?
此外,是否可以:
- 在内联定义中(仅 MSVC 支持)以某种方式引用参数?
以某种方式也在这些函数的定义中使用 function_type
(当在 class 之外完成时)。以下是可以的(所有编译器)
struct methods
{
static function_type mem_fun_static;
/* ... */
};
int methods::mem_fun_static(double) { return 0; }
这还不错,因为 function_type
的更改会导致函数定义处的编译错误(因为它将不再匹配声明)——但仍然有可能避免这种情况。
§ 8.3.5 Functions [dcl.fct] p12 A typedef of function type may be used to declare a function but shall not be used to define a function.
因此 Clang 在所有情况下拒绝代码都是正确的,接受它的编译器是错误的。
(引自N4618但规则永远是语言的一部分)
最近我了解到您可以使用函数类型的类似变量的语法来声明一个函数(包括方法):
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
类型的单个参数和 return int
值 - 正如 function_type
所说。
这么多年我都知道 C++ 而我对此一无所知 - 这种语言总是让我感到惊讶!顺便说一句 - 这种语法在任何地方都提到过 here 吗?我没看到这个...
然而,在探索这个对我来说新的功能时,我偶然发现了编译器之间的一些不一致。对于测试,我使用了以下编译器:
- GCC 5.4.0 和 7.1.0,命令行:
g++ -Wall -Wextra -pedantic -std=c++14
- Clang 4.0.1,命令行:
clang++ -Wall -Wextra -pedantic -std=c++14
- MSVC 19.10.25019 (VS 2017),命令行:
cl /W4 /EHsc
在我 运行 的测试中,两个 GCC 版本都给出了相同的结果,因此我进一步将它们称为 GCC。
= delete
不一致
struct methods
{
/* ... */
function_type mem_fun_deleted = delete;
};
- 海湾合作委员会:好的
当当:错误!
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;
};
- 海湾合作委员会:好的
当当:错误!
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
当当:错误!
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:好的
问题
这里有哪些编译器?
此外,是否可以:
- 在内联定义中(仅 MSVC 支持)以某种方式引用参数?
以某种方式也在这些函数的定义中使用
function_type
(当在 class 之外完成时)。以下是可以的(所有编译器)struct methods { static function_type mem_fun_static; /* ... */ }; int methods::mem_fun_static(double) { return 0; }
这还不错,因为
function_type
的更改会导致函数定义处的编译错误(因为它将不再匹配声明)——但仍然有可能避免这种情况。
§ 8.3.5 Functions [dcl.fct] p12 A typedef of function type may be used to declare a function but shall not be used to define a function.
因此 Clang 在所有情况下拒绝代码都是正确的,接受它的编译器是错误的。
(引自N4618但规则永远是语言的一部分)