簡體   English   中英

C ++左值,右值,引用,參數和性能

[英]C++ lvalues, rvalues, references, parameters, and performance

所以我有一個函數,需要將std :: vector作為參數。 我想知道最佳的聲明參數的方法,這樣底層數組就不會很深,因為它可能很大。

// which should I choose?
void myFunc(std::vector<char>); // 1
void myFunc(std::vector<char>&); // 2
void myFunc(std::vector<char>&&);  // 3
void myFunc(std::vector<char>*) // 4

我應該選擇哪一個? 另外,我不會在函數中修改向量,所以我不應該添加const嗎? 我應該重載該功能並結合使用嗎?

  1. 無論如何,如果要在函數中復制它:

     void myFunc(std::vector<char>); 
  2. 如果您只想讀取參數而不復制它:

     void myFunc(const std::vector<char>&); 
  3. 如果要修改傳遞給函數的原始向量,請執行以下操作:

     void myFunc(std::vector<char>&); 
  4. 如果你想優化右值, 或者如果你想移動參數到函數:

     void myFunc(std::vector<char>&&); 
  5. 如果您需要能夠表示通過引用傳遞的可選參數:

     void myFunc(const std::vector<char>*); 
  6. 如果需要傳遞非nullptr要修改的可選參數:

     void myFunc(std::vector<char>*); 

如果你不想 深拷貝 std::vector

  • 其移入您的函數:

     // foo() decalaration void foo(std::vector<int> v); // usage example std::vector<int> v {0, 1, 2, 3}; foo(std::move(v)); // v is moved into foo() and invalid now 

    您也可以通過相同的方式從函數返回此向量:

     // foo() decalaration std::vector<int> foo(std::vector<int> v) { return v.push_back(4), std::move(v); } // usage example std::vector<int> v {0, 1, 2, 3}; v = foo(std::move(v)); // now v is {0, 1, 2, 3, 4} and no one were deep copied 

    但是請注意,如果您不移動它(調用foo(v)而不是foo(std::move(v)) ),那么它將被深度復制 在底層, foo()參數v只是由move-constructor構造的

  • 通過它作為參考:

     // foo() declaration void foo(std::vector<int>& v); 

    但是現在我們有一個問題:哪些引用和cv限定詞 好吧,一般來說,我們有2種引用類型和4種cv-qualifiers類型,總共有8個聲明:

     void foo(std::vector<int>&); void foo(std::vector<int> const&); void foo(std::vector<int> volatile&); void foo(std::vector<int> const volatile&); void foo(std::vector<int>&&); void foo(std::vector<int> const&&); void foo(std::vector<int> volatile&&); void foo(std::vector<int> const volatile&&); 

    當然,其中的一部分是無用的,應該刪除。 但是盡管如此,太多的聲明也被稱為完美轉發問題 (實際上,當出現問題時就沒有右值引用,因此問題要小2倍)。

    例如,如果要修改v ,則至少需要2個功能:

     void foo(std::vector<int>&); void foo(std::vector<int>&&); 

    在這種情況下,您將能夠在左值對象上調用foo()

     std::vector<int> v; foo(v); 

    以及臨時的:

     foo(std::vector<int>{1, 2, 3, 4, 5}); 

    但是如何只為不同的引用類型和/或cv限定詞編碼一種實現? 讓我介紹通用參考文獻

     template<typename Vector> void foo(Vector&& v); 

    Vector&& 始終是引用類型 ,可以推導為

    • 如果將std::vector<int>類型的左值傳遞給foo() std::vector<int>&則為std::vector<int>&

       std::vector<int> v; foo(v); // v is lvalue 
    • 如果您傳遞類型為std::vector<int> const左值,則為std::vector<int> const&

       std::vector<int> const v; foo(v); // v is const lvalue 
    • std::vector<int>&&如果您傳遞右值:

       foo(std::vector<int>{0, 1, 2}); // v is rvalue 
    • 等等...

    但是在這種情況下,您必須檢查Vector類型的接受程度。 不過那是另一回事了。

而且在這種情況下,我絕對沒有理由傳遞指針而不是引用。

暫無
暫無

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

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