下面的代码
#include <random>
std::mt19937 generator((std::random_device())());
只用 clang 编译文件:
$ clang++ -c -std=c++0x test.cpp
但是 gcc 失败了:
$ g++ -c -std=c++0x test.cpp
test.cpp:3:47: erro: expected primary-expression before ‘)’ token
该代码在 C++11 中有效吗?它是 GCC 中的错误还是 Clang 的扩展/错误?
最佳答案
gcc 将子表达式 (std::random_device())()
解析为函数类型 std::random_device()
的转换。它有助于查看 icc 的错误输出,它比 gcc 的信息量略多:
source.cpp(6): error: cast to type "std::random_device ()" is not allowed
std::mt19937 generator((std::random_device())());
^
source.cpp(6): error: expected an expression
std::mt19937 generator((std::random_device())());
^
相关制作是5.4p2:
cast-expression:
- unary-expression
- ( type-id ) cast-expression
由于一对空括号 ()
不是一元表达式,因此该产生式不可用,编译器应从 5.2p1 中选择产生式:
postfix-expression:
- [...]
- postfix-expression ( expression-listopt )
- [...]
其中 postfix-expression 是 (std::random_device())
并且省略了 expression-list。
我已经提交了 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56239在 gcc bugzilla 上,看起来应该很快就会解决。
请注意,如果您向 operator()
提供参数,则 8.2p2 要求编译器将表达式解析为强制转换,即使强制转换为函数类型是非法的(如果有多个参数,则使用逗号运算符将参数列表解析为表达式:
(std::less<int>())(1, 2);
^~~~~~~~~~~~~~~~~~ illegal C-style cast
^~~~~~~~~~~~~~~~ type-id of function type std::less<int>()
^~~~~~ argument of C-style cast
^ comma operator
正确的写法(除了使用 C++11 通用初始化语法)是添加另一层括号,因为 type-id 不能包含外括号:
((std::less<int>()))(1, 2);
关于c++ - 使用临时函数对象进行全局初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14732132/