直接初始化条件内的对象
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'
.
除了"because the grammar says so"还有其他原因吗?我该如何解决?
我正在使用 VC++03,其中 Foo
:
- 是一个 RAII 敏感对象,我注意没有定义一个复制构造函数
- 是一个接受用户参数的模板
- 有一个双参数构造函数
...所以我宁愿避免复制它或重复它的类型。
注意:虽然我的实际问题是 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}) {
//...
}
可以在 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'
.
除了"because the grammar says so"还有其他原因吗?我该如何解决?
我正在使用 VC++03,其中 Foo
:
- 是一个 RAII 敏感对象,我注意没有定义一个复制构造函数
- 是一个接受用户参数的模板
- 有一个双参数构造函数
...所以我宁愿避免复制它或重复它的类型。
注意:虽然我的实际问题是 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}) {
//...
}