extern模板类向量<unique_ptr <...>&gt;替代

时间:2017-12-29 15:52:44

标签: c++11 templates vector unique-ptr explicit-instantiation

这开始是一个问题:“为什么不能显式实例化std :: vector_sttr的std :: vector?”如:

template class std::vector<std::unique_ptr<int>>;

虽然遵循显式实例化和变量很好:

template class std::vector<int>;
template class std::unique_ptr<int>;

int main() {
    std::vector<int> ints;
    std::vector<std::unique_ptr<int>> pointers;
}

但问题改为:“替代方案会是什么?”

我会发布我的演讲但是回答两者,因为我没有找到一个感觉相似的问题。我也在寻找替代品,如果有的话。

1 个答案:

答案 0 :(得分:1)

为什么不可能?

不可能这样做:

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技巧并且只是部分地实例化了一些可能的东西,那会很不错,但这可能会有一些问题。