Reputation: 958
I ran into some code that surprised me. This compiles in Visual Studio 2012 and runs just fine.
class Description {
public:
Description(bool valid = false);
~Description(void);
};
Description functionThatReturnsADescription()
{
return 1;
}
int main()
{
Description theDescription = functionThatReturnsADescription();
}
My confusion is with the functionThatReturnsADescription()
method; how is it legal to return any object other than Description? If I set it to return 1
, it calls the Description constructor with valid = true
. If I set it to return false
or return 0
, it calls the Description constructor with valid = false
.
Does this mean a C++ compiler always calls the functions' return type constructor with the arguments of the return statement?? How did I not know that before?! I would have swore this wasn't legal C++.
Upvotes: 0
Views: 1066
Reputation: 254431
how is it legal to return any object other than Description?
You can return any type that's implicitly convertible to Description
. In this case, any numeric type can be converted to bool
via standard conversions, then to Description
via the non-explicit constructor.
You could prevent this conversion by declaring the constructor explicit
, if you like. It's a good idea to make that a habit, to avoid unexpected conversions like this one.
Does this mean a C++ compiler always calls the functions' return type constructor with the arguments of the return statement??
If the types don't match, and there is a suitable non-explicit constructor to use for the conversion, yes.
How did I not know that before?!
C++ is a complicated language. After fifteen years, I still keep finding things I didn't know.
Upvotes: 3
Reputation: 32894
The return value 1
gets implicitly converted to boolean true
which is then passed as an argument to the constructor. A Description
object gets created implicitly using the constructor Description(bool valid = false);
.
It is to be noted that two implicit conversions are happening here: 1 → true → Description. You can prevent the second conversion by making the constructor explicit
. Change the declaration of the constructor to
explicit Description(bool valid = false);
However, the first conversion would still happen i.e. one can still do return Description(1);
.
Refer: What does the explicit keyword in C++ mean?
Upvotes: 1
Reputation: 258568
1
gets implicitly converted to true
, so the constructor accepting a bool
is chosen.
To prevent this implicit conversion, you can mark the constructor as explicit
, in which case only
return Description(1);
would work.
Upvotes: 1