【发布时间】:2018-07-25 22:36:13
【问题描述】:
为什么这段代码不起作用? std::map 的插入方法的文档中没有关于 CopyConstructibility 的内容:http://en.cppreference.com/w/cpp/container/map/insert
我可以构造 std::pair ,第二个元素是我的 non_copyable 类,但我不能将它插入到 map 中,即使 insert 方法的第一个重载采用 const value_type&,所以这应该可以正常工作。
有人能帮我理解为什么 std::map 需要这个 CopyConstructibility 吗?
#include <utility>
#include <map>
struct non_copyable {
non_copyable(){}
private:
non_copyable(const non_copyable&);
};
int main() {
std::pair<int, non_copyable> p; // this works!
std::map<int, non_copyable> m;
m.insert(std::pair<int, non_copyable>()); // this does NOT work
}
【问题讨论】:
-
因为它制作了一对的副本。
-
改用
emplace。这就是它存在的目的。 -
显式定义的复制构造函数禁用了移动构造函数的隐式定义。如果可用,您需要
non_copyable(non_copyable&&) = default;选择正确的插入重载(除非我弄错了,否则它在 c++17 中)。 -
emplace在 c++11 之前不可用。insert有不止一种形式,在 c++11 之前只有一种可用,它正在复制变量(它使用 const-lvalue 引用const T &)。但是在新标准中,您可以使用emplace,或者您可以使用insert本身与“移动”变体(采用T &&),但这需要您定义“移动”构造函数。non_copyable(non_copyable&&) = default;尝试阅读“引用类型”、“复制/移动构造函数”、“复制/移动分配”
标签: c++