簡體   English   中英

std :: list &lt;std :: unique_ptr <T> &gt;:傳遍它

[英]std::list< std::unique_ptr<T> >: passing it around

假設我有一個class Tstd::list

std::list<T> l;

將它傳遞給函數時,我會使用引用:

someFunction( std::list<T> &l )

傳遞一個std::list unique_ptr std::list的最佳方法是什么?

std::list< std::unique_ptr<T> >  l;

像這樣:

someFunction( std::unique_ptr<T> ptr )

或這個:

someFunction( T* ptr )

或這個:

someFunction( T &ref )

那么如何使用std::listback()函數調用它呢? 這些是恕我直言所有“類型”相當,但我敢肯定我在這里遺漏了一些東西。

謝謝

為了最好的情況:

  1. someFunction(const T&);
  2. someFunction(T&);
  3. someFunction(const std :: unique_ptr <T>&);
  4. someFunction(標准::的unique_ptr <T>&);

第一個是最好的,因為它不會修改它的對象,無論你如何分配它都可以使用它(例如,你可以毫無問題地切換到shared_ptr)。

無論你使用什么智能指針,第二個也會工作; 但是,它假設您可以修改對象,並且只要您可以創建const,就應該。

數字3和4都允許指向的對象發生變異; 但是,#3不允許修改智能指針,而數字4則允許。 兩者都有缺點,它們強制使用unique_ptr,而上面的兩個都可以工作,無論智能指針類。

按值傳遞unique_ptr,就像在其他一些示例中一樣,不是一個選項; unique_ptr應該是唯一的。 如果要復制它,請考慮使用shared_ptr。

對於前兩個,如果你在back()的結果上調用它,它看起來像:

someFunction(*(lst.back()));  // dereference lst.back() before passing it in.

對於后兩者,如果你在back()的resut上調用它,它看起來像:

someFunction(lst.back()); // pass the smart pointer, not the object to
                          // which the smart pointer currently points.

及格unique_ptr的價值,首先它不會編譯沒有std::move ,如果使用std::move將清空您已存儲在您的值list ,你將無法訪問它了。

這是因為unique_ptr不可復制,它沒有unique_ptr::unique_ptr(const unique_ptr<T>& other)類型的復制構造函數unique_ptr::unique_ptr(const unique_ptr<T>& other)而只有一個移動構造函數( unique_ptr::unique_ptr(unique_ptr<T>&& source) )。

unique_ptr以及包含unique_ptr的類/實例可以在std :: list(和其他容器)中使用,前提是它們已經定義了移動構造函數 class_name(class_name &&) (當然,unique_ptr有)。

當你傳遞這些元素時,你總是移動(而不是復制)它們,所以你總是在左值上使用std :: move(),就像在
my_list.push_back(std::move(my_element));
這使得您可以看到您將元素傳遞(=移動)到列表中,並且在該操作之后my_element為“空”(如空unique_ptr)。

例:

typedef std::unique_ptr<uint8_t[]> data_ptr;

class data_holder
{
private:
    int something_about_data;
    data_ptr data;
public:
    data_holder(data_ptr && _data)
        : data(std::move(_data))
    {}

    // hey compiler, please generate a default move constructor for me
    // despite of present destructor
    data_holder(data_holder &&) = default;

    ~data_holder()
    {
        // ...
    }

    bool is_empty() const { return ! bool(data); }
}

// ...
{
    // ...
    data_holder the_element(data_ptr(new uint8_t[DATA_SIZE]));

    // move the_element into the_list
    the_list.push_back(std::move(the_element));
    if (the_element.is_empty())
        std::cerr << "data_holder 'the_element' is now empty!" << std::endl;
    // ...
}

暫無
暫無

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

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