下面的代码在Visual Studio的Visual C++ 19.0编译器上编译得很好,但是gcc 5.4.0抱怨复制构造函数是私有的.
#include <map>
class CMyClass
{
public:
CMyClass(int) {};
private:
CMyClass(const CMyClass&); // I want to avoid copy construction
};
int main()
{
std::map<int, CMyClass> mymap;
mymap.emplace(0, 0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
‘CMyClass::CMyClass(const CMyClass&)’ is private
Run Code Online (Sandbox Code Playgroud)
是不是完全避免副本的副本emplace?我错过了什么吗?
这在已发布的 C++11 中无效。
C++11 标准描述了两个pair带有两个参数的构造函数:
pair(const T1& x, const T2& y);
template<class U, class V> pair(U&& x, V&& y);
Run Code Online (Sandbox Code Playgroud)
如果选择了第一个,那么由于显而易见的原因,你注定会失败。
如果与此处相关,“不能V隐式转换为second_type”,则第二个重载不参与重载决策。这里,V是int,second_type是CMyClass。可以int隐式转换为CMyClass? 不可以,因为该声明的格式CMyClass x = some_int;不正确,就像在 C++11 中一样,该声明理论上构造了一个CMyClass临时 from some_int,然后将其移动到 x 中,但CMyClass无法移动。
GCC 添加的额外重载(在允许的情况下)具有类似的约束。
C++17 大幅修改了对 的构造函数的约束pair,这具有允许代码正常工作的副作用。实施者将此视为追溯性缺陷修复,这就是 GCC 6 接受您的代码的原因。