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

Ita*_*iwa 15 c++ allocator

据我所知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;
}
Run Code Online (Sandbox Code Playgroud)
  • 为什么在C ++ 98上a.construct(p, 10)调用复制构造函数,但在C ++ 11及更高版本上为什么仅调用需要整数的构造函数?

  • 这是否意味着在C ++ 11,因为即使构造一些拷贝,省音优化Foo(int)explicit这样的呼叫作品:a.construct(p, 5)基于C ++的作品甚至11的构造是explicit什么我肯定的是它并不适用于C ++ 98如果Foo(int)explicit

  • 如果是这样,那么如果我使用某种禁用copy-elision优化来编译该语句会导致编译器失败?谢谢。

fly*_*lyx 13

这是因为construct C ++ 11中的change声明:

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)
Run Code Online (Sandbox Code Playgroud)

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

a.construct(p, 10)在C ++ 98中调用copy构造函数,因为10Foo通过Foo(int)构造函数隐式转换为。在C ++ 11中,此转换不是必需的,因为有一个匹配的构造函数带有一个int(恰好是在C ++ 98中用于转换的构造函数)。这也是添加时代码在C ++ 98中不起作用的原因explicit-它无法将转换10Foothen。