Od GCC 6 w C++ deklaracji/definicji unique_ptr<T[]>::reset
metody (nie ten, który akceptuje tylko nullptr_t
) wygląda następująco:Implementacja std :: unique_ptr <T[]> :: resetu w gcc 6
template <typename _Up,
typename = _Require<
__or_<is_same<_Up, pointer>,
__and_<is_same<pointer, element_type*>,
is_pointer<_Up>,
is_convertible<
typename remove_pointer<_Up>::type(*)[],
element_type(*)[]
>
>
>
>>
void
reset(_Up __p) noexcept
{
using std::swap;
swap(std::get<0>(_M_t), __p);
if (__p != nullptr)
get_deleter()(__p);
}
W pewnym momencie zostało to zmienione w celu implementacji N4089. Według tego dokumentu:
Funkcja ta zachowuje się tak samo jak członka resetowania podstawowego szablonu, chyba że nie bierze udziału w rozdzielczości przeciążenia chyba albo
-
U
jest tego samego typu jakpointer
, lub-
pointer
jest tego samego typu jakelement_type*
,U
jest rodzajem wskaźnikaV*
iV(*)[]
jest zamienny doelement_type(*)[]
.
Rozważmy następujący przykład:
std::unique_ptr<const char []> ptr1;
std::unique_ptr<char []> ptr2(new char[5]);
ptr1 = std::move(ptr2);
Od wersji 6 GCC produkuje błąd, twierdząc, że nie można nazwać std::swap
z const char*&
i char*&
. reset
Metoda odbywa się w rozdzielczości przeciążenia, ponieważ char[]
jest zamienna na const char[]
, ale naturalnie std::swap
oczekuje na dwa odniesienia tego samego typu.
Czy uważa się to za prawidłowe zachowanie? Jeśli tak, to dlaczego? Jeśli mogę domyślnie przekonwertować char[]
na const char[]
, dlaczego to samo nie powinno być możliwe z unique_ptr
?
Wygląda jak gcc bug, złożonym [77987] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77987) – Barry
Wygląda [Jon Wakely] (http://stackoverflow.com/users/981959/jonathan-wakely) już to naprawia. – Barry
Greate! Naprawdę był to błąd. Thx @ Barry do zgłoszenia. Zamykam pytanie. – user7020241