2012-02-22 14 views
9
std::unique_ptr<int> ptr; 
ptr = new int[3];    // error 
 
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int *' (or there is no acceptable conversion) 

Dlaczego to nie jest skompilowany? Jak mogę dołączyć macierzysty wskaźnik do istniejącej instancji unique_ptr?operator unique_ptr =

Odpowiedz

27

Po pierwsze, jeśli potrzebujesz unikalny wachlarz, sprawiają, że

std::unique_ptr<int[]> ptr; 
//    ^^^^^ 

Pozwala to inteligentne wskaźnik prawidłowego korzystania delete[] do deallocate wskaźnik, oraz określa operator[] naśladować normalną tablicę.


Następnie operator= jest zdefiniowana tylko dla odniesienia rvalue unikalnych wskaźników, a nie surowych wskaźników, a surowy wskaźnik nie można niejawnie konwertowane do inteligentnego wskaźnika, aby uniknąć przypadkowego przypisania rozkładający wyjątkowość. Dlatego surowego wskaźnika nie można bezpośrednio do niego przypisać. Prawidłowe podejście jest umieścić go do konstruktora:

std::unique_ptr<int[]> ptr (new int[3]); 
//       ^^^^^^^^^^^^ 

lub użyj .reset funkcję:

ptr.reset(new int[3]); 
// ^^^^^^^  ^

lub jawnie konwertować surowego wskaźnik unikalny wskaźnik:

ptr = std::unique_ptr<int[]>(new int[3]); 
// ^^^^^^^^^^^^^^^^^^^^^^^  ^

Jeśli może używać C++ 14, wolą make_unique function niż użycie new:

ptr = std::make_unique<int[]>(3); 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ 
+2

Powodem jest, że 'operator =' nie akceptuje 'int *' * i * konstruktor pobierający 'int *' jest oznaczony jako 'explicit' (zarówno dla' std :: unique_ptr 'i' std :: unique_ptr '). 'operator =' będący operatorem przypisania ruchu, a nie operator przypisania kopiowania nie ma z tym nic wspólnego. –

+0

@LucDanton: Racja. Zaktualizowano, aby uwzględnić to. – kennytm

2

Dodawanie do odpowiedzi z KennyTM

(od C++ 11)

tr = (decltype(tr)(new int[3])); 

Osobiście wolę to jak to czyni aktualizację typ tr łatwiejsze. (Tylko pojedyncze miejsce do aktualizacji)