unique_ptr列表,用于派生模板类

时间:2016-05-07 13:51:36

标签: c++ templates c++11 stl

我想创建一个list<unique_ptr<Base>> listOfBaseUniquePtr。这将能够给我两个:
1.独特的ptrs和
2.多态性。我可以调用每个派生类的虚函数。

某些东西对我不起作用。请看下面的代码示例:

#include <iostream>
#include <list>
#include <memory>

using namespace std;

class Base {
};

list<unique_ptr<Base>> listOfBaseUniquePtr;

template <typename T>
class Derived: public Base {

};

int main() {

    listOfBaseUniquePtr.push_back(new Derived<int>()); // <--- error
}

错误:

  

main.cpp:19:53:错误:没有匹配功能来调用
  'std :: list&gt; :: push_back(Derived )'
       listOfBaseUniquePtr.push_back(new Derived()); //&lt; ---错误
                                                       ^ main.cpp:19:53:注意:候选人是:包含在文件中   /usr/include/c++/4.8/list:63:0,
                   来自main.cpp:2:/usr/include/c++/4.8/bits/stl_list.h:1015:7:注意:void std :: list&lt; _Tp,
  _Alloc&gt; :: push_back(const value_type&amp;)[with _Tp = std :: unique_ptr; _Alloc = std :: allocator
  std :: list&lt; _Tp,_Alloc&gt; :: value_type = std :: unique_ptr]
         push_back(const value_type&amp; __x)
         ^ /usr/include/c++/4.8/bits/stl_list.h:1015:7:注意:参数1从'Derived
'到'const value_type&amp;>没有已知的转换   {aka const std :: unique_ptr&amp;}'
  /usr/include/c++/4.8/bits/stl_list.h:1020:7:注意:void std :: list&lt; _Tp,
  _Alloc&gt; :: push_back(std :: list&lt; _Tp,_Alloc&gt; :: value_type&amp;&amp;)[with _Tp = std :: unique_ptr; _Alloc = std :: allocator
  std :: list&lt; _Tp,_Alloc&gt; :: value_type = std :: unique_ptr]
         push_back(value_type&amp;&amp; __x)
         ^ /usr/include/c++/4.8/bits/stl_list.h:1020:7:注意:从'Derived *'到参数1的参数1没有已知的转换   'std :: list&gt; :: value_type&amp;&amp; {又名
  std :: unique_ptr&amp;&amp;}'make [2]:
  [CMakeFiles / uniqueptr.dir / main.cpp.o]错误1 make [1]:
  [CMakeFiles / uniqueptr.dir / all]错误2 make:[all]错误2

我做错了什么?

2 个答案:

答案 0 :(得分:3)

如果查看push_back()的签名,您会看到有两个重载。一个需要std::unique_ptr<T> const&,另一个需要std::unique_ptr<T>&&

表达式new Derived<int>()返回Derived<int>*类型;显然,这不是前面提到的类型之一;没有任何重载具有Derived<int>*参数。

你可以做两件事:

替换

listOfBaseUniquePtr.push_back(new Derived<int>());

使用

listOfBaseUniquePtr.push_back( std::make_unique<Derived<int>>() );

或者,使用emplace()的{​​{1}}成员函数系列;这是一个例子:

std::list<T>

如果要通过基类的指针删除从该基类派生的类,则基类应始终具有虚析构函数。你的基础班#39;定义应该是:

listOfBaseUniquePtr.emplace_back( new Derived<int> );

答案 1 :(得分:1)

您应该使用std::make_unique

listOfBaseUniquePtr.push_back(std::make_unique<Derived<int>>());

也不要忘记将虚拟析构函数添加到你的Base:

virtual ~Base(){}

否则〜如果使用基类指针销毁,则不会调用派生构造函数。