为什么不能用参数构造条件中定义的变量? [英] Why can't variables defined in a conditional be constructed with arguments?
问题描述
问题很简单.为什么编译:
The question is simple. Why does this compile:
bool b(true);
if (b) { /* */ }
然后编译:
if (bool b = true) { /* */ }
但不是这样:
if (bool b(true)) { /* */ }
在我的真实代码中,我需要构造一个对象并对其进行测试,同时还要在if块结束时销毁它.基本上,我正在寻找这样的东西:
In my real code, I need to construct an object and test it, while also having it destroyed when the if-block ends. Basically, I'm looking for something like this:
{
Dingus dingus(another_dingus);
if (dingus) {
// ...
}
}
当然可以,
if (Dingus dingus = another_dingus) { /* */ }
但是接下来我要构造一个 Dingus
并在其上调用 operator =
.在我看来,我可以使用任何我喜欢的构造函数来构造对象.
But then I'm constructing a Dingus
and calling operator=
on it. It seems logical to me that I would be able to construct the object using whatever constructor I please.
但是我困惑为什么这在语法上是不正确的.我已经用G ++和MSVC ++进行了测试,他们都抱怨这种构造,所以我确定它是规范的一部分,但是我对此的原因以及可能存在的不难看的解决方法感到好奇.
But I'm baffled why this isn't grammatically correct. I've tested with G++ and MSVC++ and they both complain about this construct, so I'm sure it's part of the spec but I'm curious as to the reasoning for this and what non-ugly workarounds there may be.
推荐答案
有点技术性.没有理由不能允许您想要的东西,事实并非如此.这是语法.
It's a bit technical. There's no reason why what you want couldn't be allowed, it just isn't. It's the grammar.
if
语句是一个选择语句,它采用语法形式:
An if
statement is a selection statement, and it takes the grammatical form:
if (condition) statement
在这里,条件
可以是:
-
表达式
或 -
type-specifier-seq声明符=赋值表达式
就在那里.允许在条件中进行声明是一种特殊情况,它必须遵循 that 格式,否则您的程序格式不正确.他们可能允许直接初始化而不是复制初始化,但是现在并没有任何动机.正如约翰内斯·绍布(Johannes Schaub)指出的那样,此更改将破坏现有代码,因此几乎永远不会发生.
And there you have it. Allowing a declaration in a condition is a special case, and it must follow that form or your program is ill-formed. They could have probably allow direct-initialization instead of copy-initialization, but there isn't really any motivation to do so now. As Johannes Schaub points out, this change would break existing code, so it's pretty much never going to happen.
Let_Me_Be注意,C ++ 11添加了第三种形式(我在这里忽略了属性):
Let_Me_Be notes that C++11 added a third form (I'm ignoring attributes here):
decl-specifier-seq declarator braced-init-list
所以 if(bool b {true})
很好.(这不可能破坏任何有效的现有代码.)
So if (bool b{true})
is fine. (This can't possibly break any valid existing code.)
请注意,您的问题似乎与效率有关:请放心.编译器将忽略该临时值,而直接直接构造左侧.但是,这要求您的类型是可复制的(或在C ++ 11中可移动).
Note your question seems to do with efficiency: don't worry. The compiler will elide the temporary value and just construct the left-hand side directly. This, however, requires your type be copyable (or movable in C++11).
这篇关于为什么不能用参数构造条件中定义的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!