2012-02-22 20 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) 

Por qué esto no está compilado? ¿Cómo puedo adjuntar un puntero nativo a la instancia unique_ptr existente?operador unique_ptr =

Respuesta

27

En primer lugar, si necesita un conjunto único, que sea

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

Esto permite que el puntero inteligente para utilizar correctamente delete[] desasignar el puntero, y define la operator[] para imitar una gama normal.


Entonces, el operator= sólo está definido para referencias rvalue de punteros únicos y no punteros primas, y un puntero cruda no se puede convertir implícitamente a un puntero inteligente, para evitar la asignación accidental que rompe singularidad. Por lo tanto, un puntero sin formato no puede asignarse directamente a él. El enfoque correcto se pone al constructor:

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

o utilizar la función .reset:

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

o explícitamente convertir el puntero en bruto a un puntero único:

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

Si puede usar C++ 14, prefiere el make_unique function sobre el uso de new en absoluto:

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

La razón es que 'operator =' no acepta 'int *' * y * el constructor que toma 'int *' está marcado como 'explicit' (para ambos' std :: unique_ptr 'y' std :: unique_ptr '). 'operator =' siendo un operador de asignación de movimiento y no un operador de asignación de copia no tiene nada que ver con eso. –

+0

@LucDanton: Correcto. Actualizado para incluir eso. – kennytm

2

Agregando a la respuesta de KennyTM

(puesto que C++ 11)

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

personalmente prefiero esto, ya que hace que la actualización del tipo de tr más fácil. (Solo un lugar para actualizar)

Cuestiones relacionadas