Como eu sei std::allocator<T>::construct
leva apenas dois parâmetros na versão mais antiga do C ++; o primeiro é um ponteiro para a memória bruta, não construída, na qual queremos construir um objeto do tipo T
e o segundo é um valor do tipo de elemento para inicializar esse objeto. Portanto, o copy-constructor é chamado:
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 que no C ++ 98
a.construct(p, 10)
chamando o construtor de cópias, mas no C ++ 11 e acima está chamando apenas o construtor que usa um número inteiro?Será que isso significa em C ++ 11 por causa de alguma otimização Copy-elisão mesmo que o construtor
Foo(int)
éexplicit
trabalhos sobre tal chamada:a.construct(p, 5)
funciona em C ++ 11, mesmo o construtor éexplicit
o que eu tenho certeza é que ele não funciona em C ++ 98 seFoo(int)
éexplicit
.Em caso afirmativo, se eu compilar essa instrução com algum tipo de
copy-elision
otimização desabilitante fará com que o compilador falhe? Obrigado.
Respostas:
Isso ocorre porque a declaração foi
construct
alterada no C ++ 11 :A primeira declaração chama o construtor de cópia, enquanto a segunda declaração chama um construtor que corresponde à lista de argumentos fornecida. Este poderia ser o construtor de cópia, mas também outro construtor, como você viu no seu código.
a.construct(p, 10)
chama o construtor de cópia no C ++ 98 porque o10
é implicitamente convertido emFoo
peloFoo(int)
construtor. Essa conversão não é necessária no C ++ 11, pois existe um construtor correspondente que usa umint
(exatamente o construtor usado para converter no C ++ 98). Essa também é a razão pela qual o código não funciona no C ++ 98 quando você adicionaexplicit
- ele não pode converter o arquivo10
em umFoo
então.fonte