Мой вопрос касается реализации шаблона оператора назначения shared_ptr
в GCC 4.7.2, который, как я подозреваю, содержит ошибку.
ПОМЕЩЕНИЕ 1: С++ 11 СТАНДАРТ
Вот подпись шаблона оператора присваивания, о котором я говорю:
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
Из стандарта С++ 11 (20.7.2.2.3):
"Эквивалентно shared_ptr(r).swap(*this)
."
Другими словами, шаблон оператора присваивания определяется в терминах шаблона конструктора. Подпись шаблона конструктора выглядит следующим образом:
template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
Из стандарта С++ 11 (20.7.2.2.1):
"Требуется: конструктор [...] не должен участвовать в разрешении перегрузки, если Y * неявно конвертируется в T *."
ПОМЕЩЕНИЕ 2: GCC 4.7.2 ОСУЩЕСТВЛЕНИЕ:
Теперь реализация шаблона конструктора GCC 4.7.2 кажется мне верной (std::__shared_ptr
- базовый класс std::shared_ptr
):
template<typename _Tp1, typename =
typename std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
__shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
:
_M_ptr(__r._M_ptr),
_M_refcount()
{
_M_refcount._M_swap(__r._M_refcount);
__r._M_ptr = 0;
}
Однако реализация GCC 4.7.2 шаблона оператора присваивания такова:
template<typename _Tp1>
__shared_ptr& operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
{
_M_ptr = __r._M_ptr;
_M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
return *this;
}
Что меня поражает, так это то, что эта операция не определена в терминах шаблона конструктора или swap()
. В частности, простое присваивание _M_ptr = __r._M_ptr
не дает такого же результата, как если типы _Tp1*
и _Tp*
явно проверяются на конвертируемость через std::is_convertible
(который может быть специализированным).
ПОМЕЩЕНИЕ 3: РЕАЛИЗАЦИЯ VC10
Я заметил, что VC10 имеет более подходящую реализацию в этом отношении, которую я считаю правильным и ведет себя так, как я ожидал в своих тестовых случаях (в то время как GCC не делает):
template<class _Ty2>
_Myt& operator=(const shared_ptr<_Ty2>& _Right)
{
// assign shared ownership of resource owned by _Right
shared_ptr(_Right).swap(*this);
return (*this);
}
ВОПРОС:
Есть ли ошибка в реализации GCC 4.7.2 shared_ptr
? Я не мог найти отчет об ошибке для этой проблемы.
POST SCRIPTUM:
Если вы хотите спросить меня, что такое мои тестовые примеры, почему я забочусь об этой, казалось бы, несущественной детали, и почему я, кажется, подразумеваю, что мне нужно специализироваться на std::is_convertible
, пожалуйста, сделайте это в чате. Это долгая история, и нет способа суммировать ее, не будучи неправильно понятой (со всеми ее неприятными последствиями). Заранее благодарю вас.