【发布时间】:2021-08-05 10:25:38
【问题描述】:
免责声明:我起初写了一个我认为很清楚的问题版本,但那根本不是。我在这里把它改成了 MRE。
我有以下代码:
#include <map>
#include <memory>
#include <string>
using std::make_unique;
using std::string;
using std::unique_ptr;
template <typename T>
class Holder {
public:
Holder() {}
~Holder() {}
private:
T value_; // In real life, we can do something with this.
};
struct Thing {
Thing() {}
};
class ThingCollection {
public:
ThingCollection() {}
private:
// In real life, I have more maps of <string, Thing*>.
// Which is why I use a unique_ptr in the map.
std::map<string, unique_ptr<Thing>> the_map_;
};
我的问题是将unique_ptr 转换为Holder<ThingCollection>,由于缺少复制构造函数而失败。
void foo() {
Holder<ThingCollection> cm; // OK.
auto cmp1 = make_unique<Holder<int>>(Holder<int>()); // OK.
auto cmp2 = make_unique<ThingCollection>(ThingCollection()); // OK.
auto cmp3 = make_unique<Holder<int>>(Holder<int>()); // OK.
auto cmp4 = make_unique<Holder<ThingCollection>>(Holder<ThingCollection>()); // BAD.
}
在编译时,由于复制构造函数(unique_ptr)被隐式删除,最后 (BAD) 行失败。我明白为什么unique_ptr 不可复制,但我不明白它为什么要复制到这里或正确的响应是什么。
我是这样编译的:
clang++ -std=c++14 -pthread -Wall -Wextra -c -o mre.o mre.cc
【问题讨论】:
-
“这当然会导致关于隐式删除的复制构造函数的错误” - 只是因为您可能已经实现了一个成员函数,该函数禁止从生成的移动操作。你有用户定义的
LotsOfStuff或Thing析构函数吗?如果默认移动操作适合您,请定义LotsOfStuff(LotsOfStuff&&) = default; -
事实上我必须接受你的“当然”并猜测“可能”的原因(因为它不是真的“当然”)有点表明你需要一个合适的 minimal reproducible example 而不是手-挥动代码描述。
-
我在您的
Thing课程中没有看到unique_ptr(好吧,您实际上并没有向我们展示您的Thing课程),只有在您的ThingCollection课程中。跨度> -
创建
Thing对象的管理器并使用工厂创建它们会有所帮助吗?接下来使用shared_ptr访问Thins对象? -
很明显,unique_ptr 无法管理本身包含 unique_ptr 的东西,至少不能以任何幼稚的方式进行 为什么不呢?
unique_ptr将调用它拥有的对象的析构函数,而后者又调用它包含的任何unique_ptr的析构函数
标签: c++ c++14 unique-ptr