C++中`ill-formed declaration`含义及L(n)代码行为疑问
问题核心原因是C++的「最令人头疼的解析」规则
首先明确结论:cppreference的注释没有错误,编译器的行为也完全符合C++标准,二者不存在冲突。
- C++标准有明确的解析优先级规则:任何能被解释为声明的代码,都会被优先判定为声明,而非表达式。
你给出的代码里L(n);存在两种可能的解析:
- 表达式:以全局变量
n为参数调用L的转换构造函数,创建一个L类型的临时对象 - 声明:声明一个
L类型的局部变量,变量名为n
按照优先级规则,编译器会直接采用第二种解析,也就是把L(n);等价为L n;。
接下来就能解释你观察到的所有现象:
- 编译器提示「类L不存在默认构造函数」完全合理:
L n;需要调用L的默认构造函数初始化局部变量n,而你给出的L只有一个接收M&参数的构造函数,自然会触发报错。这符合标准要求的「可诊断语义错误必须输出诊断信息」的规则,cppreference标注的ill-formed declaration正是指这个声明本身不合法。 - 添加
L() = default;后编译成功也符合标准:补充默认构造函数后,L n;这个声明就变成合法代码了,此时代码的作用是在函数f的局部作用域声明一个L类型的变量n,隐藏全局作用域的M类型变量n,完全符合语法规则。
如果你想要让L(n);按照「创建临时对象」的逻辑执行,只需要加一层括号强制打断声明解析即可:
void f() { (L(n)); // 现在会被解析为表达式,调用L(M&)创建临时对象,不需要默认构造函数即可编译 }
内容的提问来源于stack exchange,提问作者slow_down_the_pace
相关产品推荐
相关产品推荐

