直接初始化条件内的对象

Direct-initializing an object inside a condition

可以在 if 语句的条件内定义和复制初始化变量:

if(int i = 17) { ... }

这也适用于用户定义的类型,因为它们重载 operator bool :

if(Foo f = 42)      { ... }
if(Foo f = Foo(43)) { ... }

为什么我不能使用直接初始化,如下所示?

if(Foo f(51)) { ... }

GCC 发出 error: expected primary-expression before 'f'.

Live on Coliru

除了"because the grammar says so"还有其他原因吗?我该如何解决?

我正在使用 VC++03,其中 Foo :

...所以我宁愿避免复制它或重复它的类型。

注意:虽然我的实际问题是 C++03,但我(学术上)对 C++11 中的答案很感兴趣。

在C++03中,可以单独使用复制初始化语法:

selection-statement:
       if ( condition ) statement
        […]

condition:
       expression
       type-specifier-seq declarator = assignment-expression

自 C++11 起,添加了列表初始化:

condition:
        expression
       attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
       attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list

直接初始化的语法,即 Foo f(…),可能被避免的原因与它被禁止用于非静态数据成员初始化器的原因相同:歧义,特别是 "most vexing parse"。

因为C++03标准只允许在条件内进行赋值初始化:

condition:
    expression
    type-specifier-seq declarator = assignment-expression

考虑到你的限制,我相信在 C++03 中你唯一的选择是在 if 语句之外声明变量,为范围添加大括号:

{
    Foo f(51, 52);
    if (f) {
        //...
    }
}

在 C++11 中,您可以利用大括号初始化语法:

if (Foo f{51, 52}) {
    //...
}