据我所知,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;
}a.construct(p, 10)上调用复制构造函数,但是在C++11和更高版本上只调用一个整数的构造函数?Foo(int)是explicit,也适用于这样的调用:a.construct(p, 5)在C++11上工作,即使构造函数是explicit,我确信,如果Foo(int)是explicit的话,它在C++98上不起作用。copy-elision优化来编译该语句,会导致编译器失败吗?谢谢。发布于 2019-11-07 13:09:33
这是因为construct 在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中用于转换的构造函数)。这也是为什么当您添加C++98时,代码在explicit中不能工作的原因--它不能将10转换为Foo。
https://stackoverflow.com/questions/58749281
复制相似问题