Moje pytanie dotyczy implementacji szablonu operatora przypisania przypisania shared_ptr
w GCC 4.7.2, co do którego podejrzewam, że zawiera błąd.Czy istnieje błąd w implementacji przez GCC 4.7.2 operatora przypisania shared_ptr (opartego na szablonach)?
PREMISE 1: C++ 11 STANDARD
Oto podpis szablonu operatora przypisania mówię:
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
od C++ 11 Standard (20.7.2.2 .3):
"Odpowiednikshared_ptr(r).swap(*this)
."
Innymi słowy szablon operatora przydziału definiowany jest w kategoriach szablonu konstruktora. Podpis konstruktora szablonu jest następujący:
template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
Od C++ 11 Standard (20.7.2.2.1):
„wymaga: [...] konstruktor nie powinien uczestniczyć w rozdzielczości przeciążenia, chyba że Y * jest niejawnie wymienialne na T *. "
PREMISE 2: GCC 4.7.2 za REALIZACJA:
Teraz realizacja szablonie konstruktora GCC 4.7.2 wydaje mi się poprawne (std::__shared_ptr
to klasa bazowa 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;
}
Jednak implementacja szablonu operatora przypisania GCC 4.7.2 jest następująca:
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;
}
Co uderzyło mnie to, że ta operacja jest nie zdefiniowana pod względem szablonu konstruktora, ani swap()
. W szczególności, zwykłe przypisanie nie daje takiego samego rezultatu, jak gdy typy _Tp1*
i _Tp*
są wyraźnie sprawdzane pod kątem wymienialności przez std::is_convertible
(, które mogą być wyspecjalizowane).
PREMISE 3: VC10 REALIZACJA
zauważyłem, że VC10 ma bardziej Wykonanie zgodne w tym zakresie, które uważam za prawidłowe i zachowuje się zgodnie z oczekiwaniami w moich przypadków testowych (podczas gdy GCC nie robi):
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);
}
PYTANIE:
Czy rzeczywiście to błąd w realizacji shared_ptr
GCC 4.7.2 za ? Nie mogłem znaleźć żadnego zgłoszenia błędu dla tego problemu.
Post Scriptum:
Jeśli chcesz mnie zapytać, co moi przypadki testowe są dlaczego mnie obchodzi ten pozornie nieistotnych szczegółach i dlaczego wydaje się sugerować, że muszę specjalizują std::is_convertible
, zrób to na czacie. Jest to długa historia i nie ma sposobu jej podsumowania bez bycia źle zrozumianą (ze wszystkimi jej nieprzyjemnymi konsekwencjami). Z góry dziękuję.
Chyba masz tam jest niepoprawny szablon konstruktora, dałeś ten, który konwertuje z innego surowego wskaźnika, a nie ten, który konwertuje z innego 'shared_ptr' –
Nawet jeśli możesz specjalizować' is_convertible', nie możesz tego robić, chyba że utrzymujesz zachowanie wymagane przez standard ... –
@ JonathanWakely: masz rację, przepraszam. Zmienię moje pytanie: –