Student4K Student4K - 2 months ago 12
C++ Question

Strange operator ?: usage with decltype

I am reading a book, that explains C++ traits and there is an example from C++ type_traits header with a strange

?:
usage, here is the quote from the corresponding /usr/include/c++/... file:

template<typename _Tp, typename _Up>
static __success_type<typename decay<decltype
(true ? std::declval<_Tp>()
: std::declval<_Up>())>::type> _S_test(int);


Setting aside the purpose of the given declaration, the
?:
operator usage puzzles me in this code. If the first operand is
true
, then
std::declval<_Tp>()
will always be chosen as result of the evaluation.
How does that declval operand selection actually works?

Edit: originally read in Nicolai M. Josuttis's "The C++ Standard Library: A Tutorial and Reference, 2nd ed.", p.125. But there it is given in a slightly simplified form as compared to what my GCC header files has.

Answer

In the expression true ? std::declval<_Tp>() : std::declval<_Up>() the first alternative is always selected, but the whole expression must be a valid expression. So std::declval<_Up>() must be valid and that means _Up must be a callable that accepts zero arguments. Beside that, _Tp() and _Up() must return the same type (or one of the types must be implicitly convertible to another), otherwise ternary iterator would not be able to select return value.

This technique is called SFINAE. The idea is that if template instantiation fails, then it is not an error, and this template is just ignored and compiler searches for another one.