为什么这个枚举不转换为 int?
Why doesn't this enum convert to int?
为什么下面的代码不能在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);
}
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
这与"最令人烦恼的解析"来自同一个地方 - 如果它可以是一个声明,它就是一个声明的规则。
令人惊讶的是,您可以在变量声明中的标识符周围加上括号。
(我不知道为什么,但我猜它简化了C的解析器。
以下是int
变量的所有有效声明:
int (foo);
int (bar) = 0;
int (baz)(3);
int (twaddle)(baz);
问题是代码
Error(value_1);
是类型Error
的变量value_1
的声明。
这是 C 语言的遗留问题,它使用表达式作为类型声明的一部分。
例如,int *i
是指向int
的指针,因为它表示表达式*i
的计算结果应为 键入int
。更多这样的例子:
int (*func)()
是指向返回int
的函数的指针,因为表达式(*func)()
计算结果为类型int
。int *p[8]
是指向int
的指针数组,因为表达式*p[x]
计算结果为类型int
。int (*p)[8]
是指向 8int
的数组的指针 (int[8]
),因为表达式(*p)[x]
计算为类型int
。int (*(*p[8])())()
是一个包含 8 个指向函数的指针的数组,该指针返回指向返回int
的函数的指针,因为表达式(*(*p[x])())()
计算结果为类型int
。
类似地,int (i)
是int
类型的普通变量,作为表达式(i)
计算结果为int
类型。
因此,由于C++从 C 继承了这一点,因此它使用括号作为类型声明的一部分,但也在顶部添加了更多语法,从而导致一些意想不到的结果。
C++在这里应用的规则说,将所有可以成为声明的东西都视为声明。
如果经常由这样的代码引起类似的混淆:
Error ec();
它是返回Error
的函数ec
的前向声明。
main.cpp:19:18: error: 没有匹配函数来调用 'Error::Error()'
Error(value_1);
编译器尝试调用不存在的默认构造函数Error::Error()
因为它看到
Error(value_1);
作为变量声明
Error value_1;
声明允许有多余的括号。
相关文章:
- 是否可以从int转换为enum类类型
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 将字符串中的 int 转换为字母;
- 主.cpp:18:20:错误:从"int*"转换为"int"会失去精度 [-fa
- 将非常大的 int 转换为双倍,在某些计算机上会损失精度
- 如何将矢量<int>转换为字符数组?
- C++ 无法从 const int* 转换为 const_iterator
- 我不断收到错误 C2440'=':无法从"int *(__cdecl *)(int *,int *,int,int)"转换为"int *
- 如何将 int[4] 转换为 std::array<int,4>?
- 如何将data[i].int转换为vaible
- 将 int 转换为字符串,然后连接另一个变量以创建完整扩展名,然后将其转换为 const_char*
- 将私有矩阵形式 int 转换为双 C++
- 无法将参数 1 从 'int' 转换为 'int &'
- 将 int 转换为字符串后始终得到 0
- isspace 函数的性能警告,从 int 转换为布尔值
- 将大 int 转换为浮点数,而不舍入 c++
- 错误:无法将'uint8* {aka unsigned int*}'转换为"常量emxArray_uint8_T*"?
- 将未签名的INT转换为BCD
- 在 C++ 中将 int 转换为双精度