2016-01-04 56 views
14

在以下代碼段中是否需要std::move在這裏需要`std :: move`嗎?

std::function<void(int)> my_std_function; 

void call(std::function<void(int)>&& other_function) 
{ 
    my_std_function.swap(std::move(other_function)); 
} 

據我所知call()接受右值引用..但因爲右值引用本身就是一個左值,以調用swap(std::function<void(int)>&&)我已經與std::move

重鑄這一個右值引用

我的推理是否正確或在這種情況下可以省略std::move(並且如果可以,爲什麼?)

+1

好像你想發出operator =而不是swap在這裏。然後,是的,使用移動。 –

回答

18

std::function::swap不採用參數rvalue引用。這只是一個regular non-const lvalue reference。所以std::move是無益的(也許不應該編譯,因爲右值引用不允許綁定到非const左值引用)。

other_function也不需要是右值引用。

11

簽名是

void std::function<Sig>::swap(function& other) 

這樣的代碼不應該std::move編譯(MSVC具有的擴展,允許這種結合:/)

當你把R值的參考,我認爲,一個簡單的任務是你在你的情況下,想要的東西:

std::function<void(int)> my_std_function; 

void call(std::function<void(int)>&& other_function) 
{ 
    my_std_function = std::move(other_function); // Move here to avoid copy 
} 
+1

你錯過了MSVC2015夢幻般的神奇之處 – Dean

+2

@Dean這個魔術是否包括僅僅通過安裝它就可以把一個非常快的電腦變成一個熱塑性塑料塊? –

+1

@迪恩,什麼?爲什麼它是「神奇的魔術」,讓右值參考綁定到非常量左值refs?那是諷刺嗎? –

1

你是對在某種意義上—得到一個右值再次你需要std::move

但是,swap調用不需要右值或右值引用—只是一個普通的左值參考。

所以你很好,沒有std::move演員。

就移動語義而言,交換操作是相當低級的。你會發現最有用的動作最終通過一系列交換來實現,所以交換本身不使用移動語義是有意義的。真的,他們會怎麼樣?

3

在這種情況下,std::function::swap採用非常量左值引用並沒有區別。它甚至不應該與std::move編譯。

如果您使用的功能,允許右值,那麼你會需要打電話std::move作爲other_function是一個左值,即使它的類型是右值引用。例如:

struct Foo { 
    Foo()=default; 
    Foo(const Foo&) { std::cout << "copy" << std::endl; } 
    Foo(Foo&&) { std::cout << "move" << std::endl; } 
}; 

void bar (Foo&& a) { 
    Foo b {a};   //copy 
    Foo c {std::move(a)}; //move 
} 
+0

這增加了有價值的信息,而不是隻提到'swap()'需要引用,我認爲這不是問題的關鍵。 – isanae