Why does this call the default constructor?
Asked Answered
K

3

80
struct X
{
    X()    { std::cout << "X()\n";    }
    X(int) { std::cout << "X(int)\n"; }
};

const int answer = 42;

int main()
{
    X(answer);
}

I would have expected this to print either

  • X(int), because X(answer); could be interpreted as a cast from int to X, or
  • nothing at all, because X(answer); could be interpreted as the declaration of a variable.

However, it prints X(), and I have no idea why X(answer); would call the default constructor.

BONUS POINTS: What would I have to change to get a temporary instead of a variable declaration?

Knott answered 27/7, 2012 at 15:31 Comment(10)
It does the same thing if you change int answer -> any other type.Diversify
I'm not sure what X(answer) is supposed to do, but if you create an instance initialized with an int, say X xx(answer), you'll get the X(int) print.Heartland
X((int)answer); however produces the correct result.Rattan
@JTA: Because that one can never be interpreted as a declaration, so it has to be a constructor invocation.Thirtytwo
@JTA And finally, X(int(answer)); doesn't print anything, because it's a function declaration :)Knott
nothing at all, because X(answer); could be interpreted as the declaration of a variable. That declaration would also be a definition, and it triggers the execution of the default constructor... which in turn means that you answered your own question.Kunkle
@David You're a bit late to the party, can I fetch you a drink? ;)Knott
@FredOverflow: Make that a double expresso...Kunkle
@David double(expresso); there you go, declared just for you ;)Knott
@FredOverflow: I must need a definition to use it, because I am feeling no effect...Kunkle
T
73

nothing at all, because X(answer); could be interpreted as the declaration of a variable.

Your answer is hidden in here. If you declare a variable, you invoke its default ctor (if non-POD and all that stuff).

On your edit: To get a temporary, you have a few options:

Thirtytwo answered 27/7, 2012 at 15:36 Comment(11)
The static_cast<X>(answer) feels the "most C++" answer -- it's even recommended by an old GCC documentation as a way to force an rvalue.Cuprum
Won't the brace initializer also maybe incur a copy?Gwenny
@rubenvb: Why would it? It's just a fancy new way of saying X(answer) and guarantees a ctor call.Thirtytwo
@Xeo: because brace initializer syntax takes its arguments by value? (<- note the question mark)Gwenny
@rubenvb: Oh, I didn't mean that the answer is copied, I meant when the X is returned from inside the lambda.Thirtytwo
@KerrekSB But surely only before C++11, no? Now, the canonical answer will be X{answer}.Pufahl
Can anybody please explain how X(answer) is equivalent to X answer ?Flesher
@SAM: Because the standard says so. As Kerrek's answer says, the parens are optional.Thirtytwo
@Thirtytwo Common man! Just tell me how do you know every little detail about c++? I'm not asking about just this question but I've seen your other answers too. I mean, just look atvoid(), X(answer); How on earth did you find that out?!?! Also what do you refer for C++? I read TC++PL (3rd & 4th edition). Also how did you learned C++11 in such a short time?Flesher
@Thirtytwo And how many years of programming experience did you require to get to this stage?Flesher
@SAM: I recommend joining me in the Lounge chat room (check my profile), since this is getting off-topic here. :)Thirtytwo
C
67

The parentheses are optional. What you said is identical to X answer;, and it's a declaration statement.

Cuprum answered 27/7, 2012 at 15:36 Comment(0)
L
9

If you want to declare a variable of the type X, you should do it this way:

X y(answer);
Lammastide answered 27/7, 2012 at 15:39 Comment(3)
He did not ask how to make it call the X(int) ctor.Thirtytwo
Yeah but I have a small feeling that it was the thing he ment to do :)Lammastide
@WouterH: Actually, knowing Fred, it's unlikely. He's one of those folks who like to explore the dark corners of the C++ Standard and try and understand it. In a certain RPG he would have lost all his sanity points already ;)Tartary

© 2022 - 2024 — McMap. All rights reserved.