1

以下面的成員函數:轉發的引用,參考限定符和模板的成員函數

struct T { 
    template <typename X> void f(X&& x) { /* ... */ } 
}; 

在這種情況下,x是轉發參考因爲&&被用於模板的內部的功能的參數。這是預期的。

現在採取這樣的功能:

struct T { 
    template <typename X> void f(X&& x) && { /* ... */ } 
}; 

我預計this會以類似的方式進行處理;作爲轉發參考。因此,我期望下面的程序編譯和運行就好:

#include <iostream> 

struct T { 
    template <typename X> 
    bool operator<(X&& rhs) && { 
     std::cout << "&&" << std::endl; 
     return true; 
    } 
}; 

int main() { 
    T t; 
    std::cout << (t < T()) << std::endl; 
    return 0; 
} 

但是使用GCC 4.8.4和6.0.1,它沒有。相反,我得到如下:

rvalue.cpp: In function ‘int main()’: 
rvalue.cpp:13:25: error: passing ‘T’ as ‘this’ argument of ‘bool T::operator<(X&&) && [with X = T]’ discards qualifiers [-fpermissive] 
std::cout << (t < T()) << std::endl; 

這樣看來,this不是由轉發引用。 這是正確的還是錯誤的?應該將this作爲轉發參考嗎?該標準的哪部分規定了這一點?

+0

@JoachimPileborg剛剛用6.0.1試過,結果相同。雖然謝謝! – OMGtechy

回答

3

兩個&& s`這裏需要區別對待:

struct T { 
    template <typename X> void f(X&& x) && { /* ... */ } 
}; 

你是正確的在x是轉發引用。但右側的&&是對象實例的限定條件。在這種情況下,如果對象實例是右值,則只能調用f()(可能會增加混淆的是第一個&&需要x作爲轉發參考,但第二個&&將隱式對象參數作爲右值引用)。那就是:

T().f(4); // ok 

T t; 
t.f(4); // error 

這工作方式相同const資格做:

struct X { void f(); }; 
const X cx; 
cx.f(); // error 
+0

那麼這個模板不會影響'&&'如何應用到'this'? – OMGtechy

+1

@OMGtechy這些是完全獨立的概念。你不能模擬一個函數的限定條件 - 如果你想要左值和右值重載,你需要單獨使用'&' - 和'&&'限定的函數。 – Barry

+0

謝謝。標準中是否存在這種區分的地方? – OMGtechy

2

函數末尾的引用限定符指出operator<只應在LHS爲臨時時調用。記得有一個運營商可以稱爲像任何其他成員函數,所以你有什麼是

t.operator<(T()) 

t是不是暫時的。

的對象,你正在呼籲是臨時對象的operator<如果我們改變你的例子

std::cout << (T() < t) << std::endl; 

然後它工作得很好。

+0

我明白這一點,我要問的是爲什麼'this'不是像參數那樣作爲轉發參考。 – OMGtechy

+0

@OMGtechy因爲編譯器不只是將你的對象轉換成右值。如果確實如此,那麼參考資格將毫無用處。你說這個函數只能在右值上調用。當你打破它並在一個左值的對象上調用它時,你會得到一個編譯器錯誤。 – NathanOliver

+0

@OMGtechy:首先,* forwarding-reference *和* rvalue-reference *之間存在差異。其次,在一個成員函數內部,'this'既不是**轉發引用,也不是** rvalue引用,即使在只能在右值處調用的函數內部也是如此,在這種情況下'this'仍然是一個左值,綁定到* rvalue *表達式。 – Nawaz

0

成員operator<() &&可以右值只能叫,所以下面:

t < T() 

是不會工作的,因爲t不是右值 —它是左值

下面應該工作:

std::move(t) < T() 

這也太:

T{} < T{} 

請注意,我用{}因爲我更熟悉他們,他們沒有太多的驚喜工作。