0

最近我一直在嘗試理解移動語義並提出了一個問題。std :: forward實現之間的區別

該問題已被討論here

我實現了第一個變種,並檢查其是否返回L值或R值:

#include <iostream> 
using namespace std; 

template <typename T> 
T&& my_forward(T&& x) { 
    return static_cast<T&&> (x); 
} 

int main() { 
    int a = 5; 
    &my_forward(a); // l-value 
    return 0; 
} 

所以,如果我通過L值,則返回L值(編譯,因爲我可以如果我這樣做:

&my_forward(int(5)); // r-value with int&& type 

我的代碼不編譯,因爲my_forward返回的r值。在上面的問題中,他們說這個實現和標準的區別(分別是std :: remove_reference和兩個不同的參數分別是&和& &)是我的實現始終返回l值,它會返回r值和l值。

所以我想知道,爲什麼我不能實現std :: forward像那樣?在哪些具體情況下會顯示標準版本之間的區別?另外,爲什麼我應該將T指定爲模板並且不能讓它使用參數類型來定義它自己?

+0

你爲什麼試圖採取的右值引用地址? – xinaiz

+0

@BlackMoses檢查r值。 – LogicStuff

+0

@LogicStuff啊,好吧,以爲這是誤判'&'的用法:) – xinaiz

回答

3

嘗試在真實環境中將它像std一樣向前。你的不工作;

void test(std::vector<int>&&){} 

template<class T> 
void foo(T&&t){ 
    test(my_forward<T>(t)); 
} 

foo(std::vector<int>{}); 

以上不編譯。它與std::forward

除了塊參考壽命延長之外,您的轉發沒有任何用處。同時,std::forward是條件std::move

帶名稱的東西都是左值,但是向前移動右值引用的名稱。

帶名稱的左值引用是左值。

+0

非常感謝!我檢查了這個[代碼](http://ideone.com/XPePam),似乎我錯了。我沒有在真實的環境中檢查它,因爲我認爲(實際上)這些實現是相同的。我真的不明白有什麼區別。你能解釋一下嗎? – fminkin

+0

爲什麼我的實現像這樣工作?正如我們在主題中看到的那樣,它返回r值,爲什麼它不起作用呢? – fminkin

+0

**帶名稱的右值引用是左值。**直到您明白您將會感到困惑。 – Yakk

1

不幸的是,服用地址是不是在你的背景下有用的操作,因爲它着眼於一種錯誤的價值範疇的:

  • 你可以採取glvalue的地址,而不是prvalue的。一個glvalue代表一個「位置」(即一個對象所在的位置),一個prvalue代表「初始化」(即一個對象有什麼值)。

  • 您可以從右值盜取資源,但不能從左值盜取資源。左值引用綁定到左值,左值引用綁定到右值。 std::forward的要點是在提供右值時向右值賦值,當賦值左值時賦值爲左值。

std::forward返回一個右值,它實際上返回一個x值,和xvalues都是右值和glvalues:

    lvalue  f() for "T& f();", decltype(f()) is T& 
       /
      glvalue 
     /  \ 
    value    xvalue  f() for "T&& f();", decltype(f()) is T&& 
     \  /
      rvalue 
        \ 
        prvalue  f() for "T f();", decltype(f()) is T 
+0

我認爲你的意思。 「你可以從右值盜取資源,但不能從左值盜取資源。」 – Lenz

+0

@Lenz:我沒有,謝謝:-) –

相關問題