2011-08-10 38 views
15

我最近圍繞着C++ 0x的glvalues,xvalues和prvalues以及右值引用的概念。然而,有一件事還是令我困惑不解:什麼是函數類型的右值引用?

什麼是「右值引用函數類型」?它在草稿中被多次提及。爲什麼會引入這樣一個概念?它有什麼用途?

+0

你最終明白了答案嗎?我已經在答案下留下了評論,所以如果你知道澄清請提供它。謝謝 –

回答

15

我不想爲圓形,但右值參照函數T ype是函數類型的右值引用。有一種功能類型,例如void()。你可以形成一個右值引用。

N3055引入的分類系統而言,它是一個xvalue。

它的用途很少見,但它不是無用的。考慮到例如:

void f() {} 
... 
auto x = std::ref(f); 

x的類型是:

std::reference_wrapper<void()> 

如果你看一下大綱的reference_wrapper它包括:

reference_wrapper(T&) noexcept; 
reference_wrapper(T&&) = delete; // do not bind to temporary objects 

在這個例子中T是函數型void() 。因此,第二個聲明形成對函數類型的右值引用,以確保reference_wrapper不能使用右值參數構造。即使T不是常量。

如果形成函數的右值引用是不合法的,那麼即使我們沒有將右值T傳遞給構造函數,該保護也會導致編譯時錯誤。

+3

我想你的意思是'void()'。 'void()()'是GCC/binutils的錯誤解構,但[前段時間修復](http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46332)。 –

+1

@Johannes:謝謝!這是最*有用的! –

+0

這是令人毛骨悚然,我有問題的理解。關於編譯時錯誤的最後一句 - 在這種情況下SFINAE不會導致第二個聲明被忽略? – Kos

0

在下面的舊C++標準是被禁止:

int foo(); 
void bar(int& value); 

int main() 
{ 
    bar(foo()); 
} 

因爲foo的返回類型()是一個右值和通過引用傳遞到禁止()。

這被允許使用,雖然在Visual C++中啓用,因爲(我認爲)微軟擴展2005

可能的解決方法沒有的C++ 0x(或MSVC)將宣佈

void bar(const int& value); 

或使用臨時變量,儲存FOO(的返回值),並傳遞變量(作爲參考)吧():

int main() 
{ 
    int temp = foo(); 
    bar(temp); 
} 
+5

也許我誤解了這個問題,但我認爲OP正在討論對函數類型(即lambda等)的rvalues引用。 – user786653

相關問題