2011-06-10 65 views
27

我想了解爲什麼有人會寫一個函數,需要一個常量右值引用C++ 0x const RValue引用作爲函數參數

在下面的代碼示例中const rvalue引用函數的用途是什麼(返回「3」)。 爲什麼重載分辨率優先於常量LValue引用函數(返回「2」)之上的const Rvalue。

#include <string> 
#include <vector> 
#include <iostream> 

std::vector<std::string> createVector() { return std::vector<std::string>(); } 

//takes movable rvalue 
void func(std::vector<std::string> &&p) { std::cout << "1"; } 

//takes const lvalue 
void func(const std::vector<std::string> &p) { std::cout << "2"; } 

//takes const rvalue??? 
//what is the point of const rvalue? if const I assume it is not movable? 
void func(const std::vector<std::string> &&p) { std::cout << "3"; } 

int main() 
{ 
    func(createVector()); 
    return 0; 
} 
+0

你使用什麼編譯器? – 2011-06-10 14:11:41

+0

VC++ 10。但在gcc上應該是一樣的。 VC++ 10具有符合標準的移動語義和重載解析。 – 2011-06-10 14:16:28

+0

dupe of http://stackoverflow.com/questions/4938875/do-rvalue-references-to-const-have-any-use – 2011-06-10 14:43:45

回答

28

左值強烈希望綁定左值引用,並且類似右值引用強烈希望綁定右值引用。可修飾的表達式較弱地偏向於綁定到非const引用。

所以,當你的編譯器做重載決策時,它會檢查是否有一個超載需要右值引用,因爲這是首選強。在這種情況下,由於experssion是可修改的右值,所以右值參考超載獲勝。

實際上有const const rvalue引用的用法,它們可以用來確保不會綁定到右值。請記住,一個右值綁定到一個const左值的參考,因此,如果你這樣做:

template <typename T> void foo(const T& bar) { /* ... */ } 

並與被調用的函數:

foo(createVector()); 

它會正常工作。然而,有時需要確保您只能將左值傳遞給函數(對於其中的一個,這是std::ref的情況)。您可以通過添加過載實現這一目標:

template <typename T> void foo(const T&&) = delete; 

記住,右值強烈希望結合右值引用,並修改表達式喜歡弱綁定到非const引用。由於我們有一個常量右值引用,它基本上意味着每個右值都會綁定到這個值,因此如果您嘗試將右值傳遞給foo(),編譯器會給出錯誤。這是實現這種功能的唯一方式,因此有時很有用。

+0

謝謝你的深入的答案。當你說:「左值強烈地綁定左值引用」你是什麼意思?我不認爲LValues可以綁定到RValues。我誤解了你嗎? – 2011-06-10 14:45:50

+1

左值可以綁定到常量右值引用。 *任何*都可以綁定到常量左值引用以及常量右值引用。 – 2011-06-10 14:47:41

+3

這實際上並沒有給出理由,爲什麼const rvalues本身是有用的,只是爲什麼你可能需要const rvalue引用。 – Puppy 2011-06-10 15:22:34

2

重載決策程序首選常量左值常量右值,因爲,它是一個右值,你就綁定到一個右值引用,但你必須在這兩種情況下添加常量,所以右值引用肯定是首選。

這樣的事情通常是沒有意義的 - 最好讓它們綁定到const lvalue重載。常數rvalues沒有任何實際用途。

相關問題