旧的 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;
}
为什么在 C++98 a.construct(p, 10)
上调用复制构造函数,但在 C++11 及更高版本上只调用采用整数的构造函数?
这是否意味着在 C++ 11 上,因为某些复制省略优化,即使构造函数 Foo(int)
是 explicit
也适用于此类调用:a.construct(p, 5)
适用于C++11 甚至构造函数是 explicit
如果 Foo(int)
是 explicit
.
[=34,我确定它在 C++98 上不起作用=]
如果是这样,那么如果我使用某种禁用 copy-elision
优化来编译该语句,会导致编译器失败吗?谢谢。
这是因为construct
changed 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
然后。
据我所知,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 上,因为某些复制省略优化,即使构造函数
[=34,我确定它在 C++98 上不起作用=]Foo(int)
是explicit
也适用于此类调用:a.construct(p, 5)
适用于C++11 甚至构造函数是explicit
如果Foo(int)
是explicit
.如果是这样,那么如果我使用某种禁用
copy-elision
优化来编译该语句,会导致编译器失败吗?谢谢。
这是因为construct
changed 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
然后。