【问题标题】:extern template class vector<unique_ptr<...>> alternativeextern 模板类 vector<unique_ptr<...>> 替代
【发布时间】:2018-06-10 00:56:59
【问题描述】:

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

template class std::vector&lt;std::unique_ptr&lt;int&gt;&gt;;

虽然下面的显式实例化和变量很好:

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

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

但问题变成了:“有什么选择?”

我将发布我的演练来回答这两个问题,因为我没有找到一个感觉足够相似的问题。我也在寻找替代品,如果有的话。

【问题讨论】:

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


    【解决方案1】:

    为什么不可能?

    这是不可能的:

    template class std::vector&lt;std::unique_ptr&lt;int&gt;&gt;; // (1)

    虽然编译器对这样一个变量完全没问题:

    std::vector&lt;std::unique_ptr&lt;int&gt;&gt; vec; // (2)

    据我所知,(2)是可能的,因为使用复制分配/构造函数的方法永远不会在向量中隐式实例化;
    并且 (1) 是不可能的,因为向量试图实例化试图在 unique_ptr 上复制的方法。

    例如第一个不为 gcc 7.2.1 c++17 编译的方法是vector::push_back(const T&amp;);

    因为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&lt;UniquePtrWithMovingCopy&lt;int&gt;&gt;;

    所以我想,虽然我试图找到答案,但毕竟是我自己找到的,但我很高兴听到其他一些方法或修复方法。

    不过,如果编译器执行某种 sfinae 技巧并且仅部分实例化任何可能的东西,那就太好了,但这可能有它自己的一些问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-08
      • 2014-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 2023-03-16
      相关资源
      最近更新 更多