我有一些使用容器的代码让我感到悲伤。问题是我想在其中一个子域中放置一个智能指针(unique_ptr)。例如:
struct subrecord {
int id;
int handle;
std::list<std::unique_ptr<some_really_big_record>> update; // <-- Problem field
};
struct database {
std::map <std::string, subrecord> name_subrec_map;
std::vector <std::string> a_names;
std::vector <std::string> b_names;
};
在我尝试添加update
字段之前,所有内容都已正常编译。一旦我这样做,编译器开始抱怨该unique_ptr没有可用的复制操作符。这很公平,它不应该有一个。我并不打算复制这些地图条目。
但是,编译器没有告诉我这个副本来自我的代码的哪个位置。现在还有相当多的东西。有什么好办法可以说出来吗?我已经尝试搜索update
和name_subrec_map
的引用并对其进行评论,但根本没有任何运气。唯一能消除错误的是评论update
字段本身。
我讨厌必须切换到shared_ptr,因为我无法找到dang副本。
答案 0 :(得分:3)
如果您的代码在某处复制子记录,则可能会隐藏在您的错误消息中。
由于子记录是可移动但不可复制的,您可以将其放在标题中:
struct subrecord
{
// ...
subrecord( const subrecord & ) = delete;
subrecord( subrecord&& ) = default;
};
您甚至可以暂时注释掉列表成员,看看是否有任何编译器错误出现在调用此副本的位置。
注意:
如果您的编译器不支持delete和default,请将复制构造函数设为私有,但您还必须将移动构造函数设置为public。
如果这只是查找编译器错误的临时措施,则可以跳过实现它,因为您不关心链接错误。您将在以后删除它,但还必须删除私有拷贝构造函数。
虽然你确实优先实现它,因为这会暴露代码中任何进一步的尝试来复制子记录,而不会给任何敢于编写错误消息地狱的人。