Comme je sais, std::allocator<T>::construct
ne prend que deux paramètres sur l'ancienne version de C ++; le premier est un pointeur vers une mémoire brute non construite dans laquelle nous voulons construire un objet de type T
et le second est une valeur de type d'élément pour initialiser cet objet. Ainsi, le constructeur de copie est invoqué:
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;
}
Pourquoi en C ++ 98
a.construct(p, 10)
appeler le constructeur de copie mais en C ++ 11 et supérieur appelle juste le constructeur qui prend un entier?Est -ce que cela signifie sur C ++ 11 en raison d'une optimisation copie-élision , même si le constructeur
Foo(int)
est desexplicit
travaux sur cet appel:a.construct(p, 5)
travaux sur C ++ 11 même le constructeur estexplicit
ce que je suis sûr est qu'il ne fonctionne pas sur C ++ 98 siFoo(int)
estexplicit
.Si oui, alors si je compile cette déclaration avec une sorte d'
copy-elision
optimisation désactivante , le compilateur échouera? Je vous remercie.
Réponses:
En effet, la déclaration de
construct
changé en C ++ 11 :La première déclaration appelle le constructeur de copie, tandis que la deuxième déclaration appelle un constructeur qui correspond à la liste d'arguments donnée. Cela pourrait être le constructeur de copie, mais aussi un autre constructeur comme vous l'avez vu dans votre code.
a.construct(p, 10)
appelle le constructeur de copie en C ++ 98 car le10
est implicitement converti enFoo
via leFoo(int)
constructeur. Cette conversion n'est pas nécessaire en C ++ 11 car il existe un constructeur correspondant qui prend unint
(exactement le constructeur qui a été utilisé pour la conversion en C ++ 98). C'est également la raison pour laquelle le code ne fonctionne pas en C ++ 98 lorsque vous ajoutezexplicit
- il ne peut pas convertir le10
en aFoo
then.la source