直接初始化条件内的对象

Direct-initializing an object inside a condition

本文关键字:对象 条件 初始化      更新时间:2023-10-16

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

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

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

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

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

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

GCC发射CCD_ 3。

在Coliru 上直播

除了"因为语法这么说"之外,还有其他原因吗?我该如何解决它?

我使用的是VC++03,其中Foo:

  • 是一个RAII敏感对象,为此我注意而不是定义复制构造函数
  • 是接受用户参数的模板
  • 有一个双参数构造函数

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

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

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

选择语句
 nbsp nbsp;if (条件)语句
nbsp nbsp […]

条件
 nbsp nbsp表达式
nbsp nbsp 类型说明符seq声明符=赋值表达式

从C++11开始,增加了列表初始化:

条件
 nbsp nbsp表达式
 nbsp nbsp属性说明符seqoptdecl说明符seq声明符=初始值设定项子句
 nbsp nbsp属性说明符seqoptdecl说明符seq声明符支持的初始列表

直接初始化的语法,即Foo f(…),可能被避免了,原因与非静态数据成员初始化程序不允许使用的原因相同:歧义,特别是"最麻烦的解析"。

因为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}) {
    //...
}