When reading the implementation of std::pair
in gcc source code, I found one of the default constructors as below:
template<typename _T1, typename _T2>
struct pair
: public __pair_base<_T1, _T2>
{
typedef _T1 first_type; ///< The type of the `first` member
typedef _T2 second_type; ///< The type of the `second` member
_T1 first; ///< The first member
_T2 second;
...
template <typename _U1 = _T1,
typename _U2 = _T2,
typename enable_if<__and_<
__is_implicitly_default_constructible<_U1>,
__is_implicitly_default_constructible<_U2>>
::value, bool>::type = true>
constexpr pair()
: first(), second() { }
...
}
My question is, when using the default ctor to construct an object, it's also the time to instantiate an object of the class as below:
std::pair<int, double> p;
How can _U1
be different from _T1
? Thank you guys.
It can't1. By defaulting the constructor template arguments _U1
and _U2
to the class template parameters _T1
and _T2
, there is scope for the substitution failure with the third (unnamed) non-type template parameter.
This is the mechanism by which that overload isn't available when either _T1
or _T2
isn't implicitly default constructable.
_U1
and _U2
can be explicitly specified, so the only source is the default. Normal function templates can have explicit parameters, e.g. std::pair<int, double> pair; pair.operator=<char, float>({'a', 1.0f})