2013-04-01 71 views
3

我不清楚返回const值對C++ 11中移動語義的影響。在C++ 11中返回const值類型對移動語義的影響

這兩個函數是否有區別,它們返回數據成員?在C++ 11中,const仍然是多餘的?

int GetValueA() { return mValueA; } 
const int GetValueB() { return mValueB; } 

這些功能呢?

int GetValuesAB() { return mValueA + mValueB; } 
const int GetValuesCD() { return mValueC + mValueD; } 
+8

沒有區別導致'int'是原始類型 –

+0

@ Cheersandhth.-Alf:Spot on! :) –

+0

可能的重複[應使用返回類型的無用類型限定符,爲清晰起見?](http://stackoverflow.com/questions/1579435/should-useless-type-qualifiers-on-return-types-be-用於清晰) –

回答

5

一個表達式調用一個按值返回的函數是一個prvalue。但是,也有非類非陣列類型(§5/ 6)的無const prvalues:

如果prvalue最初具有類型爲「CV T」,其中T是CV-不合格非類,非數組類型,在進行任何進一步分析之前,表達式的類型被調整爲T

這意味着你的兩個函數定義沒有區別。是否返回const int或僅僅是int是無關緊要的,因爲表達式從不是const

但是,當您返回類類型時有區別。請看下面的例子:

struct foo 
{ 
    void bar() { std::cout << "Hello" << std::endl; } 
}; 

foo get_foo(); 

現在,如果我們調用get_foo(),我們得到了一個臨時foo對象。這個prvalue不是const,我們可以調用非const成員函數,所以我們可以愉快地做get_foo().bar()。但是,我們可以這樣修改申報get_foo

const foo get_foo(); 

現在,表達get_foo()const prvalue(這是允許的,因爲它是一個類類型),我們不能返回的臨時對象調用bar它再一次。

儘管如此,討論非類類型的移動語義沒有意義,因爲int永遠不會移出。如果您返回const類別類別,則該類型也可能因爲const而無法移出。爲了證明:

foo get_foo(); 
foo f(get_foo()); // Will call the move constructor 

const foo get_foo(); 
foo f(get_foo()); // Will call the copy constructor 

這是因爲const prvalue不會綁定到非const右值引用,這是移動的構造函數作爲其參數。

+0

如果'void bar()'是'void bar()const',我們能夠在臨時對象上調用它嗎? –

+0

@ M.Dudley是的,你會的。我剛剛添加了一些關於移動語義的內容,因爲我忘記了原來的答案。 –

+0

'foo(foo const && f)'將構造函數移動到救援? (就像有超過1個拷貝構造函數一樣......) – Yakk