2010-06-22 61 views
42

我不明白的例子中的最後一行的FCD(§7.6.1.2/ 4)的第148頁:decltype和括號

const int&& foo(); 
int i; 
struct A { double x; }; 
const A* a = new A(); 
decltype(foo()) x1 = i;  // type is const int&& 
decltype(i) x2;    // type is int 
decltype(a->x) x3;   // type is double 
decltype((a->x)) x4 = x3; // type is const double& 

爲什麼括號在這裏做一個區別?它不應該簡單地像double一樣嗎?

回答

35

只是,上面的例子,它說

  • 如果e是一個括號的ID-表達或類成員訪問(5.2.5),decltype(e)是由命名實體的類型即
  • 如果e是左值,則decltype(e)是T &,其中T是e的類型;

我認爲decltype(a->x)是的「類成員訪問」的一個例子和decltype((a->x))是左值的一個例子。

+0

但是,這並不能解釋const :) – fredoverflow 2010-06-22 23:11:27

+5

@FredOverflow:是否:'a'的類型爲'const A *' – Cubbi 2010-06-22 23:12:30

+1

我怎麼看不到const?謝謝:) – fredoverflow 2010-06-22 23:17:35

8

添加的parens將它變成左值。

MSDN says
內部圓括號會導致語句被評估爲表達式而不是成員訪問。因爲a被聲明爲一個const指針,所以這個類型是對const double的引用。

16
decltype(a->x) 

這給你的成員變量A::x,這是double的類型。

decltype((a->x)) 

這給你的表達(a->x),這是一個左值表達式的類型(因此爲什麼它是一個const reference-- aconst A*)。

+4

好吧,我明白這些規則現在可以在這裏應用,但*爲什麼*是這樣的規則?爲什麼區分'a-> x'和'(a-> x)'是有意義的?這對我來說似乎是隨機的。爲什麼我會想要這種行爲?有任何想法嗎? – fredoverflow 2010-06-23 09:51:07

+0

謝謝,但'decltype(f())'和'decltype((f()))'在我的系統上產生了'int'。我誤解了你嗎? – fredoverflow 2010-08-30 19:21:21

+0

@Fred:沒關係。我錯了。在這種情況下,括號會被忽略,所以兩者都應該是'const int'。 – 2010-08-31 02:17:00