为什么std :: map\templace需要gcc上的拷贝构造函数?

Ber*_*ert 5 c++ gcc c++11

下面的代码在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?我错过了什么吗?

T.C*_*.C. 4

这在已发布的 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”,则第二个重载不参与重载决策。这里,Vintsecond_typeCMyClass。可以int隐式转换为CMyClass? 不可以,因为该声明的格式CMyClass x = some_int;不正确,就像在 C++11 中一样,该声明理论上构造了一个CMyClass临时 from some_int,然后将其移动到 x 中,但CMyClass无法移动。

GCC 添加的额外重载(在允许的情况下)具有类似的约束。


C++17 大幅修改了对 的构造函数的约束pair,这具有允许代码正常工作的副作用。实施者将此视为追溯性缺陷修复,这就是 GCC 6 接受您的代码的原因。

  • 好的,但是你怎么能做到这一点呢?有没有办法在 std::map (GCC &lt;6) 中放置不可复制的可构造对象? (2认同)