Как я знаю, std::allocator<T>::construct
принимает только два параметра в более старой версии C ++; первый - указатель на необработанную неструктурированную память, в которой мы хотим создать объект типа, T
а второй - значение типа элемента для инициализации этого объекта. Итак, конструктор копирования вызывается:
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;
}
Почему в C ++ 98
a.construct(p, 10)
вызов конструктора копирования, а в C ++ 11 и выше вызывает только тот конструктор, который принимает целое число?Означают ли это на C ++ 11 из - за некоторую оптимизацию копирования Elision даже если конструктор
Foo(int)
являетсяexplicit
работой по такому вызову:a.construct(p, 5)
работает на C ++ 11 даже конструктор ,explicit
что я уверен , это не работает на C ++ 98 , еслиFoo(int)
естьexplicit
.Если так, то если я скомпилирую это утверждение с каким-то отключением
copy-elision
оптимизации, это приведет к сбою компилятора? Спасибо.
Ответы:
Это потому, что объявление об
construct
изменении в C ++ 11 :Первое объявление вызывает конструктор копирования, а второе - конструктор, который соответствует заданному списку аргументов. Это может быть как конструктор копирования, так и другой конструктор, как вы видели в своем коде.
a.construct(p, 10)
вызывает конструктор копирования в C ++ 98, потому что10
он неявно преобразуетсяFoo
вFoo(int)
конструктор. Это преобразование не является необходимым в C ++ 11, поскольку существует соответствующий конструктор, который принимаетint
(именно тот конструктор, который использовался для преобразования в C ++ 98). Это также причина , почему код не работает в C ++ 98 при добавленииexplicit
- он не может преобразовать10
кFoo
тогда.источник