Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

c++ - 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) { /* */ }

And this compile:

if (bool b = true) { /* */ }

But not this:

if (bool b(true)) { /* */ }

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

Of course, this would work:

if (Dingus dingus = another_dingus) { /* */ }

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.

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

An if statement is a selection statement, and it takes the grammatical form:

if (condition) statement

Here, condition can be either:

  • expression or
  • type-specifier-seq declarator = assignment-expression

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 notes that C++11 added a third form (I'm ignoring attributes here):

decl-specifier-seq declarator braced-init-list

So if (bool b{true}) is fine. (This can't possibly break any valid existing code.)


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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...