Reputation: 126
I decided to have a play with trailing return types with delctype shown below:
template<typename T, typename U>
auto Add(T t, U u) ->decltype(t,u)
{
return t + u;
}
this works perfectly fine if I send in integers or doubles e.g.
Add(10,11); //21
Add(5.35,2.22); //7.57
but then I asked myself will this work on boolean arithmetic?
Add(true,true); // = 1 + 1 = 1;
Add(true, false); // = 1 + 0 = 1
Add(false, false); // = 0 + 0 = 0;
In this case it worked fine but then I decided to try the following instead:
->decltype(t + u)
Which gave me the result:
Add(true,true); // = 1 + 1 = 2;
Add(true, false); // = 1 + 0 = 1
Add(false, false); // = 0 + 0 = 0;
I'm presuming the decltype(t+u) is deducing the return type as int instead of bool? why is this? and is there a hierarchy of types decltype will choose?
Upvotes: 1
Views: 503
Reputation: 11126
Short answer: Because the type of the expression is int
and not bool
Long answer: By calling Add(true, true)
your template type parameters T
and U
are deduced to be bool. Therefore, the type of the expression t, u
is bool
. Note that the comma in this expression is the comma operator, as pointed out by @ccom.
Since you cannot arithmetically add bools (the symbol +
is sometimes used in logic to denote the or operator which is |
in c++), c++ will automatically promote both bools to integers and then perform the addition.
In the case decltype(t, u)
, your return type is bool, and therefore another implicit cast happens, forcing your integer of 2 to become a boolean value (true, or 1, when converted back to int)
In the case decltype(t + u)
the return type is the type of the expression (int
) and therefore the final conversion is simply not done - giving you 2.
Upvotes: 5
Reputation: 76280
The key point here is that the expression bool + bool
is of type int
, because no operator+
would make sense with bool
eans.
Considering that an operator+
for int
s exists, and that the Standard specifies at §4.5/6 that:
A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.
the prvalue of true
is promoted to 1
and the prvalue of false
is promoted to 0
.
This can be easily seen by the result of:
std::cout << (true + true);
which is 2
.
In your first case the decltype(t, u)
is obviously bool
since both t
and u
are bool
.
In the second case, instead the decltype(t + u)
, for the above reasons, is int
.
Upvotes: 2