简体   繁体   English

std :: unique_ptr和模板:为什么此代码无法编译?

[英]std::unique_ptr and templates: Why won't this code compile?

I am working on a templated component system for a game. 我正在为游戏创建模板化的组件系统。 It holds items in a vector and has two partial specializations: One for POD types and another that uses std::unique_ptr. 它在矢量中保存项目,并具有两个部分的专业化:一个用于POD类型,另一个用于std :: unique_ptr。 The templated specialization for the vector of std::unique_ptr doesn't compile but using a vector of std::unique_ptr's in non-templated code works fine. std :: unique_ptr的向量的模板专用化不能编译,但是在非模板代码中使用std :: unique_ptr的向量可以正常工作。 I have searched for a solution to this problem, but unfortunately my knownledge of C++11/C++14 isn't refined enough; 我已经在寻找解决此问题的方法,但是不幸的是,我对C ++ 11 / C ++ 14的了解还不够。 what am I doing wrong? 我究竟做错了什么?

Minimal example (stripped to the problem area): 最小示例(跳至问题区域):

#include <vector>
#include <memory>

template<typename T>
class component 
{
    public:
    class handle
    {
    friend class component;
    protected:
        std::size_t inner;
    };

    component<T>::handle add(const T& t)
    {
        items.push_back(t);
        handle h;
        h.inner = items.size() - 1;
        return h;
    }

    protected:
        std::vector<T> items;
};


template<typename T>
class component<std::unique_ptr<T>> 
{
    public:
    class handle
    {
    friend class component;
    protected:
         std::size_t inner;
    };

    component<std::unique_ptr<T>>::handle add(const std::unique_ptr<T>& t)
    {
        items.push_back(std::move(t));
        handle h;
        h.inner = items.size() - 1;
        return h;
    }

    protected:
    std::vector<std::unique_ptr<T>> items;
};

Here is the testing code 这是测试代码

int main()
{
    // This works fine.
    component<int> pod_component;
    pod_component.add(5);

    // This works, too!
    std::vector<std::unique_ptr<int>> pointer_vector;
    pointer_vector.push_back(std::make_unique<int>(5));

    component<std::unique_ptr<int>> pointer_component;
    // Why doesn't this compile?
    pointer_component.add(std::make_unique<int>(5));

    return 0;
 }

Here is the error output from gcc (4.9.3 Gentoo): 这是gcc(4.9.3 Gentoo)的错误输出:

 error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

I hope that someone better at C++ than myself can help both me and future readers understand this tricky question. 我希望比我自己更擅长C ++的人可以帮助我和未来的读者理解这个棘手的问题。

The problem is here: 问题在这里:

component<std::unique_ptr<T>>::handle add(const std::unique_ptr<T>& t)   
{                                 //        |
    items.push_back(std::move(t));// <------+
    // ...

std::move applied to a const lvalue returns a const rvalue reference. std::move应用于const左值将返回const右值引用。 Thus, it is bound by the push_back(const value_type&) overload rather than the push_back(value_type&&) one, which means that it tries to copy the unique_ptr passed as an argument. 因此,它受push_back(const value_type&)重载约束,而不是受push_back(value_type&&) push_back(const value_type&)重载约束,这意味着它试图复制作为参数传递的unique_ptr

The correct declaration should look as follows: 正确的声明应如下所示:

component<std::unique_ptr<T>>::handle add(std::unique_ptr<T>&& t)
//                                                         ~^^~

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c++ std::unique_ptr 不会在地图中编译 - c++ std::unique_ptr won't compile in map 类型不完整的 std::unique_ptr 将无法编译 - std::unique_ptr with an incomplete type won't compile 为什么std :: shared_ptr <T> = std :: unique_ptr <T[]> 编译,而std :: shared_ptr <T[]> = std :: unique_ptr <T[]> 才不是? - Why does std::shared_ptr<T> = std::unique_ptr<T[]> compile, while std::shared_ptr<T[]> = std::unique_ptr<T[]> does not? 如果没有 noexcept 移动构造函数,为什么带有 std::vector 的代码不能编译,但带有 std::unique_ptr 的代码却可以编译? - Why does code with std::vector not compile but with std::unique_ptr it does, if there is no noexcept move constructor? unique_ptr(std :: nullptr_t)和模板 - unique_ptr(std::nullptr_t) and templates 为什么list <unique_ptr>中的unique_ptr的std :: move()没有真正移动它? - Why doesn't std::move() of unique_ptr from list<unique_ptr> really move it? 为什么 std::unique_ptr 不允许自己可复制? - Why doesn't std::unique_ptr allow itself to be copyable? 解除引用unique_ptr的原因不会修改原始对象 - Why dereferencing a unique_ptr won't modify the original object 分配std :: vector <std::unique_ptr<T> &gt;到另一个std :: vector <std::unique_ptr<T> &gt; - Assign std::vector<std::unique_ptr<T>> to another std::vector<std::unique_ptr<T>> 为什么std :: unique_ptr没有像std :: shared_ptr这样的别名构造函数? - Why doesn't std::unique_ptr have an aliasing constructor like std::shared_ptr has?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM