【问题标题】:List of unique_ptr, for a derived template classunique_ptr 列表,用于派生模板类
【发布时间】:2023-03-16 09:55:01
【问题描述】:

我想创建一个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 >::push_back(Derived)'
listOfBaseUniquePtr.push_back(new Derived()); // ^ 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<_tp> _Alloc>::push_back(const value_type&) [with _Tp = std::unique_ptr; _Alloc = std::allocator
std::list<_tp _alloc>::value_type = std::unique_ptr]
push_back(const value_type& __x)
^ /usr/include/c++/4.8/bits/stl_list.h:1015:7:注意:没有已知的参数 1 从“Derived
”到“const value_type&
的转换 {又名 const std::unique_ptr&}'
/usr/include/c++/4.8/bits/stl_list.h:1020:7: 注意: void std::list<_tp> _Alloc>::push_back(std::list<_tp _alloc>::value_type&&) [with _Tp = std::unique_ptr; _Alloc = std::allocator
std::list<_tp _alloc>::value_type = std::unique_ptr]
push_back(value_type&& __x)
^ /usr/include/c++/4.8/bits/stl_list.h:1020:7:注意:没有已知的参数 1 从“派生*”到
的转换 'std::list >::value_type&& {aka
std::unique_ptr&&}' make[2]:
[CMakeFiles/uniqueptr.dir/main.cpp.o] 错误 1 ​​make[1]:
[CMakeFiles/uniqueptr.dir/all] 错误 2 make: [all] 错误 2

我做错了什么?

【问题讨论】:

  • push_back(make_unique&lt;Derived&lt;int&gt;&gt;()) 应该可以完成这项工作。

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


【解决方案1】:

如果您查看push_back() 的签名,您会看到有两个重载。一个是std::unique_ptr&lt;T&gt; const&amp;,另一个是std::unique_ptr&lt;T&gt;&amp;&amp;

表达式new Derived&lt;int&gt;() 返回一个Derived&lt;int&gt;* 类型;显然,这不是前面提到的任何一种类型;所有重载都没有Derived&lt;int&gt;* 参数。

你可以做两件事:

替换

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

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

或者,使用std::list&lt;T&gt;emplace() 系列成员函数;这是一个例子:

listOfBaseUniquePtr.emplace_back( new Derived<int> );

如果派生自该基类的类将通过基类的指针被删除,则您的基类应始终具有虚拟析构函数。你的基类的定义应该是:

class Base
{
public:
    virtual ~Base() = default;
};

【讨论】:

  • 谢谢,我找不到这个std::make_unique,因为我使用的是 g++4.8,而不是 4.9 :(。所以我使用了这个实现:stackoverflow.com/questions/24609271/…
  • @hudac 虽然我建议使用std::make_unique,但您也可以简单地使用listOfBaseUniquePtr.push_back( std::unique_ptr&lt;Derived&lt;int&gt;&gt;( new Derived&lt;int&gt; ) );
【解决方案2】:

你应该使用std::make_unique:

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

别忘了给你的 Base 添加虚拟析构函数:

virtual ~Base(){}

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

【讨论】:

    猜你喜欢
    • 2016-02-17
    • 2015-04-10
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多