【发布时间】:2017-12-17 21:27:46
【问题描述】:
最近我了解到您可以使用函数类型的类变量语法声明一个函数(包括方法):
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 的任何地方都提到过这种语法吗?我没看到这个...
但是,在探索这个新功能时,我偶然发现了编译器之间的一些不一致。对于测试,我使用了以下编译器:
- 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;
};
- GCC:好的
-
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;
};
- GCC:好的
-
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; }
};
-
GCC:错误!
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:好的
问题
这里有哪些编译器?
此外,是否有可能:
- 在内联定义中(仅受 MSVC 支持)以某种方式引用参数?
-
不知何故在这些函数的定义中使用
function_type(当在类之外完成时)。以下是可以的(所有编译器)struct methods { static function_type mem_fun_static; /* ... */ }; int methods::mem_fun_static(double) { return 0; }这并没有那么糟糕,因为
function_type的更改应该会导致函数定义处的编译错误(因为它将不再匹配声明) - 但仍然有可能避免这种情况。
【问题讨论】:
-
好问题!意识到这一点,但除了指定预期回调函数的类型(主要是在 C 代码中也是如此)之外,几乎没有什么实际用途。
-
@StoryTeller 实际上我就是这样发现的! - 使用我们拥有的框架的“线程主”回调。
-
令人惊讶的是,这些函数的前向声明如何变得不言自明,不是吗?我也喜欢指针语义没有隐藏在别名后面。
-
顺便说一句,它也可以用作
std::function的类型参数。同样,更多的自我记录代码。 -
@AdamBadura 这可能不是你的错!我有时发现谷歌搜索 foo bar stackoverflow 产生的结果比 SO 自己的重复查找器更有用,这很不幸,但仍然是一个方便的备份。