为什么下面的代码不能在g ++(C++ 14),MSVC(C++ 14)或ARM(C++ 03)下编译?
命名的Error实例调用整数构造函数,但匿名的Error实例无法解析.
class Error
{
public:
Error(int err) : code_(err) {}
const int code_;
};
enum Value
{
value_1
};
int main()
{
// compiles
Error e(value_1);
// does not compile under G++, ARM, or MSVC
Error(value_1);
}
Run Code Online (Sandbox Code Playgroud)
G ++下的示例错误:( Coliru链接)
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:19:18: error: no matching function for call to 'Error::Error()'
Error(value_1);
^
main.cpp:4:5: note: candidate: Error::Error(int)
Error(int err) : code_(err) {}
^~~~~
main.cpp:4:5: note: candidate expects 1 argument, 0 provided
main.cpp:1:7: note: candidate: constexpr Error::Error(const Error&)
class Error
^~~~~
main.cpp:1:7: note: candidate expects 1 argument, 0 provided
main.cpp:1:7: note: candidate: constexpr Error::Error(Error&&)
main.cpp:1:7: note: candidate expects 1 argument, 0 provided
Run Code Online (Sandbox Code Playgroud)
mol*_*ilo 38
这来自与"最令人烦恼的解析"相同的地方 - 规则如果它可以是一个声明,它就是一个声明.
令人惊讶的是,您可以在变量声明中将标识符放在标识符周围.
(我不知道为什么,但我猜它在当天简化了C的解析器.)
以下是int变量的所有有效声明:
int (foo);
int (bar) = 0;
int (baz)(3);
int (twaddle)(baz);
Run Code Online (Sandbox Code Playgroud)
Sta*_*irl 34
问题是代码
Error(value_1);
Run Code Online (Sandbox Code Playgroud)
是value_1类型变量的声明Error.
这是C语言的遗留问题,它使用表达式作为类型声明的一部分.
例如int *i是指向,int因为它表示表达式*i应该评估为键入int.更多这样的例子:
int (*func)()是一个指向函数返回的指针,int因为表达式(*func)()求值为type int.int *p[8]是一个指针数组,int因为表达式*p[x]求值为type int.int (*p)[8]是一个指向8 int'(int[8])数组的指针,因为表达式(*p)[x]求值为type int.int (*(*p[8])())()是一个由指向函数返回指针的函数的8个指针数组,int因为表达式(*(*p[x])())()求值为type int.类似的int (i)是类型的普通变量,int因为表达式(i)求值为type int.
因此,因为C++从C继承了它,所以它使用括号作为类型声明的一部分,但也在顶部添加了更多语法,从而导致一些意想不到的结果.
C++在这里应用的规则是将所有可以作为声明的声明视为声明.
如果经常由这样的代码引起类似的混淆:
Error ec();
Run Code Online (Sandbox Code Playgroud)
这是ec返回函数的前向声明Error.
Bo *_*son 13
main.cpp:19:18:错误:没有匹配函数来调用'Error :: Error()'
错误(value_1);
编译器尝试调用不存在的默认构造函数,Error::Error()因为它看到了
Error(value_1);
Run Code Online (Sandbox Code Playgroud)
作为变量声明
Error value_1;
Run Code Online (Sandbox Code Playgroud)
允许声明具有冗余括号.
| 归档时间: |
|
| 查看次数: |
3039 次 |
| 最近记录: |