Following on from this answer, it seems these constructors:
template<class U, class V> pair(pair<U, V>&& p);
template<class U, class V> pair(const pair<U, V>& p);
are forbidden from participating in overload resolution when they would require an explicit conversion.
From C++11 (§20.3.2, n3290):
Remark: This constructor shall not participate in overload resolution unless U is implicitly convertible to first_type and V is implicitly convertible to second_type.
An interesting SFINAE workaround has been suggested, but this digresses from the text of the standard.
How can a conforming implementation possibly exclude this from overload resolution, short of some special internal compiler magic? I.e. can an implementation do this and can I duplicate it for my own type perhaps? There doesn't seem to be anyway of conforming with this! Is it a hangover from the removal of concepts from C++11?
I did wonder about using a private constructor to do the SFINAE part and delegating from the public constructor, but it doesn't look like constructor delegation participates in SFINAE in such a way as to make that work.
but this digresses from the text of the standard
An implementation is allowed to add default arguments to any non-virtual library member function. This seems to permit precisely this kind of SFINAE tricks.
I was missing two pieces of information:
gcc uses this:
template<class _U1, class _U2, class = typename
std::enable_if<std::is_convertible<_U1, _T1>::value
&& std::is_convertible<_U2, _T2>::value>::type>
pair(_U1&& __x, _U2&& __y)
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
The trick seems to be in the default for the anonymous class
template parameter. I'd not seen that before and this implementation didn't use that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With