2016-07-27 44 views
1

該方案如下:傳遞右值加薪不能綁定到左值

#include <iostream> 
using namespace std; 

template <typename F, typename T1, typename T2> 
void flip2(F f, T1 &&t1, T2 &&t2) 
{ 
     f(t2, t1); 
} 

void g(int &&i, int &j) 
{ 
     cout << i << " " << j << endl; 
} 

int main(void) 
{ 
     int i = 1; 
     flip2(g, i, 42); 
} 

編譯器會抱怨:

error: rvalue reference to type 'int' cannot bind to lvalue of type 'int' 

但我的理解,爲T2進行實例化int,然後類型t2int&&,所以應該允許它傳遞到函數g的第一個參數(int &&)。

我的理解有什麼問題?

回答

4
f(t2, t1); 

t2有一個名字,所以它是一個左值。它是類型是右值,但在表達式中它的類型是左值。爲了傳遞它作爲右值引用,您需要使用std::forwardmove或鑄造在這裏不合適,因爲T1和T2實際上是通用引用,不是右值引用,請參閱編輯)。

#include <iostream> 
using namespace std; 

template <typename F, typename T1, typename T2> 
void flip2(F f, T1 &&t1, T2 &&t2) 
{ 
     f(std::forward<T2>(t2), std::forward<T1>(t1)); 
} 

void g(int &&i, int &j) 
{ 
     cout << i << " " << j << endl; 
} 

int main(void) 
{ 
     int i = 1; 
     flip2(g, i, 42); 
} 

http://ideone.com/Aop2aJ

---爲什麼---

考慮:

template<typename T> 
void printAndLog(T&& text) { 
    print(text); 
    log(text); 
} 

int main() { 
    printAndLog(std::string("hello, world!\n")); 
} 

當你使用一個變量的名字,表達型是左值(?glvalue);丟棄右值。否則在上面的例子中,我們已經失去了textprint()。取而代之的是,我們必須明確,當我們希望我們的右值表現得像一個:

template<typename T> 
void printAndLog(T&& text) { 
    print(text); 
    log(std::forward<T>(text)); // if text is an rvalue, give it up. 
} 

---編輯---

我用std::forward因爲T1&&T2&&是普遍引用,而不是右值引用。 https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

+0

我不明白爲什麼t2是左值,t2的類型是int &&,這看起來像一個右值引用。 – Charles0429

+0

@ Charles0429 t2有一個名字,你可以把它的地址,所以,它是一個左值。它可以綁定到右值的事實並不意味着它是一個右值 – Amadeus

+0

@ Charles0429請參閱編輯。 – kfsone

相關問題