我想创建一个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
我做错了什么?
答案 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(){}
否则〜如果使用基类指针销毁,则不会调用派生构造函数。