Mike
Mike

Reputation: 126

Trailing return type with decltype boolean arithmetic

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

Answers (2)

danielschemmel
danielschemmel

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

Shoe
Shoe

Reputation: 76280

The key point here is that the expression bool + bool is of type int, because no operator+ would make sense with booleans.

Considering that an operator+ for ints 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

Related Questions