簡體   English   中英

std :: unique_ptr和模板:為什么此代碼無法編譯?

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

我正在為游戲創建模板化的組件系統。 它在矢量中保存項目,並具有兩個部分的專業化:一個用於POD類型,另一個用於std :: unique_ptr。 std :: unique_ptr的向量的模板專用化不能編譯,但是在非模板代碼中使用std :: unique_ptr的向量可以正常工作。 我已經在尋找解決此問題的方法,但是不幸的是,我對C ++ 11 / C ++ 14的了解還不夠。 我究竟做錯了什么?

最小示例(跳至問題區域):

#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;
};

這是測試代碼

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;
 }

這是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)...); }

我希望比我自己更擅長C ++的人可以幫助我和未來的讀者理解這個棘手的問題。

問題在這里:

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

std::move應用於const左值將返回const右值引用。 因此,它受push_back(const value_type&)重載約束,而不是受push_back(value_type&&) push_back(const value_type&)重載約束,這意味着它試圖復制作為參數傳遞的unique_ptr

正確的聲明應如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM