簡體   English   中英

方法重載導致 C++ 移動語義和代碼重復

[英]C++ move semantics and code duplication as a result of method overloading

在開始之前,我在其他 stackoverflow 帖子中沒有找到可以完全解釋我的問題的任何內容,因此我決定創建自己的。 抱歉,如果它已經在其他地方得到了回答(如果它確實存在,請把我指向現有的帖子)。

假設我們在一個類中有以下兩個方法:

int do_stuff(Thing& thing){ /* Do stuff... */} // L-value version
int do_stuff(Thing&& thing){ /* Do stuff... */} // R-value version

從我讀過的內容來看,現代 C++ 幾乎已經放棄了這種邏輯,並且建議只通過值傳遞Thing ,讓編譯器來做它的魔法。 我的問題是,如果我想有兩個單獨的方法來顯式處理 L 值/R 值並避免代碼重復,以下哪一個是最好的(性能明智和最佳實踐)?

int do_stuff(Thing& thing){ return do_stuff(std::move(thing)); } // The L-value version uses the R-value one

或者

int do_stuff(Thing&& thing){ return do_stuff(thing); } // The R-value version uses the L-value one since text is an L-value inside the scope of do_stuff(Thing&&)

編輯:這個問題的目的是讓我理解這個簡單的移動語義案例,而不是創建一個有效的 C++ API。

編輯 #2:問題的printstd::string部分用作示例。 他們可以是任何東西。

編輯 #3:重命名示例代碼。 這些方法確實修改了 Thing 對象。

如果print沒有改變任何東西而只打印字符串,最好采用const std::string &作為const std::string &能夠綁定到左值和右值。

int print(const std::string& text) {}

按值傳遞參數並不意味着它不能是rvalue引用。 &&只是意味着參數必須是一個rvalue引用。 沒有&&並不意味着參數不能rvalue引用。

當參數僅由功能使用,並與我的意思是,如果它不修改,聲明你的功能最好的辦法是:

int do_stuff(const Thing& thing);

這樣,讀者很清楚thing不會被修改。 對於大多數其他情況,您應該簡單地將函數聲明為:

int do_stuff(Thing thing);

按值傳遞參數,而不是按引用或rvalue引用。

以前寫這樣的代碼很常見:

int do_stuff(Thing& thing)
{
    /* change thing so that the caller can use the changed thing */
    return success; // where success is an int
}

但是,如今,通常更喜歡返回修改后的東西:

Thing do_stuff(Thing thing) { /* return modified thing */ }

在上面的例子中:

int do_stuff(Thing thing);

調用者決定thing是否應該是副本:

do_stuff(my_thing); // copy - I need the original my_thing
do_stuff(std::move(thing)); // no copy - I don't need the original my_thing

請注意,此do_stuff聲明涵蓋了您的兩個版本:

int do_stuff(Thing&);
int do_stuff(Thing&&);

也就是說,你幾乎從不需要這樣的函數:

int do_stuff(Thing&&);

除非對於不能像stream對象一樣復制的對象。

性能沒有區別。 std::move除了轉換其參數的類型之外什么都不做,因此智能編譯器將省略對std::move的調用,甚至省略對do_stuff的冗余調用。 您可以-O2看到,在任何一種情況下,GCC 都會將調用另一個do_stuffdo_stuff編譯為一個簡單的jmp命令到另一個do_stuff

所以這是基於意見的哪種方式更好。 我個人喜歡第二種方式,因為它更短。

暫無
暫無

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

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