为什么不可能?
这是不可能的:
template class std::vector<std::unique_ptr<int>>; // (1)
尽管编译器对这样的变量完全没有问题:
std::vector<std::unique_ptr<int>> vec; // (2)
据我所知,(2)是可能的,因为使用复制分配/构造函数的方法永远不会在向量中隐式实例化;
并且 (1) 是不可能的,因为向量试图实例化试图在 unique_ptr 上复制的方法。
例如,第一种不为 gcc 7.2.1 c++17 编译的方法是vector::push_back(const T&);
因为 T = unique_ptr,而 unique_ptr 显然不支持复制操作。
有哪些替代方案?
shared_ptr 而不是 unique_ptr 有效,因为它支持复制分配,同时看起来也很干净。但正如我听说的那样,它有一些开销,并且无意共享资源所有权。
我还想象编写一个包装器,它定义了“复制”操作,它实际上会继续复制甚至抛出,例如:
template<typename T>
struct UniquePtrWithCopy {
/*mutable if move is used*/ std::unique_ptr<T> mPtr;
UniquePtrWithCopy() = default;
explicit UniquePtrWithCopy(std::unique_ptr<T>&& other)
: mPtr{std::move(other)} {
}
UniquePtrWithCopy(const UniquePtrWithCopy& other) {
mPtr = std::move(other.mPtr); // needed for operations, like resize
// or
throw std::runtime_error{"This is not intended"};
}
UniquePtrWithCopy& operator =(const UniquePtrWithCopy& other) {
if(this != &other) {
mPtr = std::move(other.mPtr);
}
return *this;
// or
throw std::runtime_error{"This is not intended"};
}
};
然后这是可能的:
template class std::vector<UniquePtrWithMovingCopy<int>>;
所以我想,虽然我试图找到答案,但毕竟我自己已经找到了,但我很高兴听到其他一些方法或修复。
但是,如果编译器做了某种 sfinae 技巧并且只部分实例化任何可能的东西,那就太好了,但这可能有它自己的一些问题。