旧的 alloctaor::construct 与新的 alloctaor::construct 和显式构造函数有什么区别?

What is the difference betwwen the older alloctaor::construct and the new one and explicit constructor?

据我所知,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;
}

这是因为constructchanged in C++11的声明:

void construct( pointer p, const_reference val );  (1)  (until C++11)
template< class U, class... Args >
void construct( U* p, Args&&... args );            (2)  (since C++11)

第一个声明调用复制构造函数,而第二个声明调用匹配给定参数列表的构造函数。这可能是复制构造函数,也可能是您在代码中看到的另一个构造函数。

a.construct(p, 10) 在 C++98 中调用复制构造函数,因为 10 通过 Foo(int) 构造函数隐式转换为 Foo。这种转换在 C++11 中不是必需的,因为有一个匹配的构造函数接受 int(正是在 C++98 中用于转换的构造函数)。这也是为什么当您添加 explicit 时代码在 C++98 中不起作用的原因——它无法将 10 转换为 Foo 然后。