【问题标题】:Variadic template expansion, inheritance, and std::unique_ptr可变模板扩展、继承和 std::unique_ptr
【发布时间】:2017-04-21 00:53:28
【问题描述】:

我有这样的代码:

#include <memory>
#include <vector>

using namespace std;

struct A {
    virtual ~A() = default;
};

struct B : public A {
};

template<typename... Ts> struct C {
    C() : v_({new Ts...}) {}

    ...

    std::vector<A*> v_;
};

...

C<B, B, A> bba;

我想使用std::unique_ptr 和std::make_unique 来避免显式调用new 并迭代v_ 以在析构函数中将其删除(v_ 将变为std::vector&lt;std::unique_ptr&lt;A&gt;&gt;)但无法弄清楚如何将std::make_unique 与初始化列表和可变参数扩展结合起来(我怀疑是因为std::unique_ptr 只能移动)。有什么建议?

【问题讨论】:

  • 它改变了问题,但为什么std::vector&lt;std::unique_ptr&lt;A&gt;&gt; 而不是std::tuple&lt;std::unique_ptr&lt;Ts&gt;...&gt;?如果集合预计会更改内容签名,则构造函数应该是模板,而不是类。

标签: c++ c++11 c++14 variadic-templates unique-ptr


【解决方案1】:

像下面这样的C 构造函数呢?

   // C++11 version (std::make_unique() unavailable in C++11)
   C()
    { 
      using unused = int[];

      v_.reserve(sizeof...(Ts));

      (void)unused { 0, ( v_.emplace_back( new Ts ), 0 )... };
    }

   // C++14 version
   C()
    { 
      using unused = int[];

      v_.reserve(sizeof...(Ts));

      (void)unused { 0, ( v_.emplace_back( std::make_unique<Ts>() ), 0 )... };
    }

unused 中的初始 0(来自 aschepler 的建议(谢谢!))允许定义

C<> etl; 

C 的类型列表为空。

【讨论】:

  • 我会在 u 中添加一个额外的 0,以便 C&lt;&gt; 工作。为什么你的“C++14版本”不能在C++11中使用?
  • @aschepler - 好主意,额外的 0,我会使用它;第二个解决方案是 C++14,只是因为(如果我没记错的话)std::make_unique() 是一个(从)C++14 功能。
猜你喜欢
  • 1970-01-01
  • 2016-05-27
  • 2014-08-26
  • 2012-04-05
  • 2021-12-19
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多