2010-10-30 59 views
11

C++ 03§4.2N°1:
左值或類型的右值「陣列NT的」或「的陣列T的未知邊界「可以轉換爲類型爲」指向T的指針「的右值。結果是指向數組的第一個元素的指針。我想可能想出了陣列型的右值的一個例子

很長時間以來,我一直在困惑的是,我並不完全理解數組類型的右值意味着什麼。也就是說,我無法想出一個表達式,其類型是一個數組,結果是一個右值。我讀this線程,它基本上提出相同的問題,並且接受的答案是「不,數組類型不存在右值」。我想我可能會對此產生矛盾。

C++ 03§5.2.5N°4:(約爲表達E1.E2)
如果E2是一個非靜態數據成員,和E1的類型是「CQ1 VQ1 X「,並且E2的類型是」cq2 vq2 T「,該表達式指定由第一個表達式指定的對象的指定成員。如果E1是一個左值,那麼E1.E2是一個左值。

我認爲否則它是一個右值(E2提供的是不是一個參考,這種情況下,由§5.2.5 N°3覆蓋),因此...

struct A 
{ 
    int a[4]; 
}; 
A f() 
{ 
    A a; 
    return a; 
} 
int main() 
{ 
    f().a; //I think this is an rvalue of array type... 
} 

在這裏我看到兩個選項:
選項1:我是對的,歡呼,好,很酷。在這種情況下,問題是:還有其他例子嗎?
選項2:我錯了,在這種情況下,問題是:這是標準的缺陷嗎?

我不知道1,但我真的懷疑2,因爲當他們談論函數到指針的轉換時,他們只提到了函數類型的左值(顯然理解這裏沒有右值)。所以他們很可能會想到數組類型的右值。

所以,基本上我的問題是我是否沒有拿出數組類型的右值的一個例子,如果沒有,請提供一個有效的,我相信stongly存在。

回答

11

是的,你是對的。該表達式是數組類型的右值。這不是一個缺陷 - 委員會知道它,它也是C89中的一個常見問題,它只允許轉換爲數組類型左值的指針。因此,您無法索引或取消引用像f().a這樣的數組。 C99解決了這個問題,並且C++沒有問題。

請注意,無論它是否是右值都與表達式是否表示對象無關。 C++ 03意外地忽略了一個數組類型的右值表達式表示一個對象。這在C++ 0x by DR#450中修復。

(明顯升值,有沒有這樣的右值)

其實有函數類型的右值。這些出現在由類成員表示的非靜態成員函數中訪問表達式

struct A { void f(); }; 

/* A().f is an rvalue of type "void()" */ 
int main() { A().f(); } 
+0

謝謝!所以你知道這是否是右值數組的唯一情況,這是由。或 - >。還有其他的例子嗎? – 2010-10-30 10:23:21

+0

@Armen我想不出另一種情況(對於C++ 03)。 – 2010-10-30 10:27:16

+1

@Armen注意到,因此,即使將數組聲明爲const const a [4];',Comeau也表示'A()。a'的類型爲int [4]'。這是因爲該標準表示非類類型的rvalues從來沒有cv限定,並且因爲EDG前端對數組及其元素類型進行cv限定爲雙向等效(請參閱核心問題#1059)。 – 2010-10-30 10:32:31

-3

的A是一個rvalue。它裏面的數組不是。想象一下你在那個臨時對象上有一個方法鏈的情況 - 它內部的變量存在多於一個方法調用和返回,並且它們可以將引用(對於鏈的持續時間有效)傳遞給其他函數。這些功能不能預先知道它們應該被稱爲右值。

在草案的最新版本,您可以在右值/左值*此超載功能。但是,即使如此,右值引用並不會使所引用的右值的內容成爲可能,並且我不完全確定ANY編譯器目前是否支持此值,並且我知道MSVC不支持此值。

逸岸,使用decltype,和您可以輕鬆確定編譯器調用數組左值。

考慮:

template<typename A, typename B> auto sum(A&& a, B&& b) -> decltype(std::forward<A>(a) + std::forward<B>(b)) { 
    return std::forward<A>(a) + std::forward<B>(b); 
} 

這就是decltype是因爲,它左值和右值之間最肯定的區別。或者,考慮這一點:

int main() 
{ 
    auto var = f().a; 
} 

var是int *。這是一個瞬間失敗,因爲f()。a立即死亡。我不確定我的立即意見,但它肯定對一個右值無效。

+0

decltype不區分rvalues和lvalues。並請再次閱讀我的第二次報價。 – 2010-10-30 10:17:22

+0

@阿門:decltype的全部點是區分。如果完美的轉發甚至開始工作,還有什麼可能呢 – Puppy 2010-10-30 10:42:47

+2

@DeadMG decltype(expr)是expr的類型。 expr是否是左值還是右值與它的類型無關。 – 2010-10-30 10:44:16

相關問題