我怎样才能找到副本的来源?
How can I find the source of a copy?
我有一些使用容器的代码让我很伤心。问题是我想在其中一个子字段中放置一个智能指针 (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,只是因为我找不到该死的副本。
如果您的代码在某处复制子记录,它可能会隐藏在您的错误消息中。
由于子记录是可移动但不可复制的,你可以把它放在它的header:
struct subrecord
{
// ...
subrecord( const subrecord & ) = delete;
subrecord( subrecord&& ) = default;
};
您甚至可以暂时注释掉列表成员,看看在调用此副本时是否出现任何编译器错误。
注意:
如果您的编译器不支持 delete 和 default,请将复制构造函数设为私有,但您还必须将移动构造函数设为 public。
如果这只是查找编译器错误的临时措施,您可以跳过实施它,因为您不关心 link 错误。您稍后将删除它,但还必须删除私有 copy-constructor。
尽管您最好实施它,因为这会暴露代码中复制子记录的任何进一步尝试,而不会给任何敢于这样做的人编译器错误消息地狱。
我有一些使用容器的代码让我很伤心。问题是我想在其中一个子字段中放置一个智能指针 (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,只是因为我找不到该死的副本。
如果您的代码在某处复制子记录,它可能会隐藏在您的错误消息中。
由于子记录是可移动但不可复制的,你可以把它放在它的header:
struct subrecord
{
// ...
subrecord( const subrecord & ) = delete;
subrecord( subrecord&& ) = default;
};
您甚至可以暂时注释掉列表成员,看看在调用此副本时是否出现任何编译器错误。
注意:
如果您的编译器不支持 delete 和 default,请将复制构造函数设为私有,但您还必须将移动构造函数设为 public。
如果这只是查找编译器错误的临时措施,您可以跳过实施它,因为您不关心 link 错误。您稍后将删除它,但还必须删除私有 copy-constructor。
尽管您最好实施它,因为这会暴露代码中复制子记录的任何进一步尝试,而不会给任何敢于这样做的人编译器错误消息地狱。