Проблема (в C ++ 03) состоит в том, что большинство реализаций стандартной библиотеки не соответствуют стандарту.В частности, стандарт гласит, что когда std::pair<T,U>
строится из другого std::pair<V,W>
, члены создаются неявными преобразованиями.Проблема в том, что на самом деле очень трудно (если вообще возможно) ограничить это преобразование в реализации шаблонного конструктора pair
, поэтому в текущих реализациях выполняется явное преобразование аргументов:
template <typename T, typename U>
struct pair {
// ...
template <typename V, typename W>
pair( pair<V,W> const & p ) : first( p.first ), second( p.second ) {}
};
На самом деле я написал сообщение в блоге об этом конкретном случае здесь , и ради него я попытался предоставить соответствующие конструкторы преобразования здесь , но решение не является стандартнымсоответствует (т. е. имеет другую подпись, чем та, которая требуется стандартом).
Примечание: в C ++ 11 (§20.3.2p12-14) это неявное преобразование также запрещено (из FDIS):
template<class U, class V> pair(pair<U, V>&& p);
Требуется: is_constructible :: value - true и is_constructible :: value - true.
Эффекты: конструктор инициализирует сначала std :: forward (p.first) и второйс помощью std :: forward (p.second).
Примечание. Этот конструктор не должен участвовать в разрешении перегрузки, если только U неявно преобразуется в first_type, а V неявно преобразуется в second_type.
Эквивалентные ограничения присутствуют в p9-11 дляэквивалент для template<class U, class V> pair(const pair<U, V>& p);
(в случае, если типы не подвижные )