Como sé std::allocator<T>::construct
, solo toma dos parámetros en la versión anterior de C ++; el primero es un puntero a la memoria sin construir, en bruto, en la que queremos construir un objeto de tipo T
y el segundo es un valor de tipo de elemento para inicializar ese objeto. Entonces se invoca el constructor de copia:
struct Foo {
Foo(int, int) { cout << "Foo(int, int)" << endl; }
/*explicit*/ Foo(int) { cout << "Foo(int)" << endl; }
Foo(const Foo&) { cout << "Foo(const Foo&)" << endl; }
};
int main(int argc, char* argv[]) {
allocator<Foo> a;
Foo* const p = a.allocate(200, NULL); // second parameter is required on C++98 but on C++11 it is optional
// Foo* const p = a.allocate(200); // works fine on C++11 but not on C++98
a.construct(p, 5, 7); // works on C++ 11 and up but not C++98
a.construct(p, 10);// works on both
a.destroy(p);
a.destroy(p + 1);
a.deallocate(p, 200);
std::cout << std::endl;
}
¿Por qué en C ++ 98
a.construct(p, 10)
llamando al constructor de copia pero en C ++ 11 y superior está llamando solo al constructor que toma un entero?¿Quiere decir esto en C ++ 11 debido a una optimización de copia-elisión incluso si el constructor
Foo(int)
esexplicit
obras en dicha llamada:a.construct(p, 5)
obras en C ++ 11 incluso el constructor esexplicit
lo que estoy seguro es de que no funciona en C ++ 98 siFoo(int)
esexplicit
.Si es así, si compilo esa declaración con algún tipo de
copy-elision
optimización de desactivación, ¿ hará que falle el compilador? Gracias.
Respuestas:
Esto se debe a la declaración de
construct
cambio en C ++ 11 :La primera declaración llama al constructor de copia, mientras que la segunda llama a un constructor que coincide con la lista de argumentos dada. Este podría ser el constructor de copia, pero también otro constructor como viste en tu código.
a.construct(p, 10)
llama al constructor de copia en C ++ 98 porque10
se convierte implícitamente aFoo
través delFoo(int)
constructor. Esta conversión no es necesaria en C ++ 11 ya que existe un constructor coincidente que toma unint
(exactamente el constructor que se utilizó para convertir en C ++ 98). Esta es también la razón por la cual el código no funciona en C ++ 98 cuando agregaexplicit
, no puede convertirlo10
en unFoo
archivo.fuente