为什么将括号与默认构造函数一起使用会导致创建变量?
Why does using parentheses with a default constructor result in creation of the variable?
看完 Louis Brandy 在 CppCon 2017 上的演讲后,我震惊地发现这段代码实际上可以编译:
#include <string>
int main() {
std::string(foo);
return 0;
}
并且出于某种原因 std::string(foo)
它与 std::string foo
相同,即声明一个变量。我发现它绝对违反直觉,并且看不出 C++ 以这种方式工作的任何理由。我希望这会给出有关未定义标识符 foo
.
的错误
它实际上使像 token1(token2)
这样的表达式比我之前想象的有更多可能的解释。
所以我的问题是:这种恐怖的原因是什么?什么时候真正需要这条规则?
P.S。抱歉,标题措辞不佳,请随时更改!
因为这个问题被标记了 language-lawyer, the direct answer is that, from [stmt.ambig]:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (
. In those cases the statement is a declaration.
同样,对于函数,在 [dcl.ambig.res]:
The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration.
因此:
Why oh why is std::string("foo")
so different from std::string(foo)
前者不能声明。后者 可以 是一个声明,带有一组多余的括号。因此,前者 不是 声明,而后者 是 .
潜在的问题是,在语法上,声明符可以以 (
开头,这可能使其与函数式显式类型转换无法区分。与其想出任意复杂的规则来尝试确定用户的意思,语言只是选择一个,并且用户很容易修复代码以实际执行他的意思。
看完 Louis Brandy 在 CppCon 2017 上的演讲后,我震惊地发现这段代码实际上可以编译:
#include <string>
int main() {
std::string(foo);
return 0;
}
并且出于某种原因 std::string(foo)
它与 std::string foo
相同,即声明一个变量。我发现它绝对违反直觉,并且看不出 C++ 以这种方式工作的任何理由。我希望这会给出有关未定义标识符 foo
.
它实际上使像 token1(token2)
这样的表达式比我之前想象的有更多可能的解释。
所以我的问题是:这种恐怖的原因是什么?什么时候真正需要这条规则?
P.S。抱歉,标题措辞不佳,请随时更改!
因为这个问题被标记了 language-lawyer, the direct answer is that, from [stmt.ambig]:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a
(
. In those cases the statement is a declaration.
同样,对于函数,在 [dcl.ambig.res]:
The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration.
因此:
Why oh why is
std::string("foo")
so different fromstd::string(foo)
前者不能声明。后者 可以 是一个声明,带有一组多余的括号。因此,前者 不是 声明,而后者 是 .
潜在的问题是,在语法上,声明符可以以 (
开头,这可能使其与函数式显式类型转换无法区分。与其想出任意复杂的规则来尝试确定用户的意思,语言只是选择一个,并且用户很容易修复代码以实际执行他的意思。