2012-02-27 68 views
4

我有:decltype(*&fun)很奇怪嗎?

#include <type_traits> 
#include <stdio.h> 

void f() { printf("foo\n"); } 

int main() 
{ 
    printf("%d %d %d\n", 
    std::is_same<decltype(*&f),decltype(f)>::value, 
    std::is_function<decltype(*&f)>::value, 
    std::is_function<decltype(f)>::value); 
    (*&f)(); 
    return 0; 
} 

其產生

0 0 1 
foo 

對於g ++ 4.6.1和4.7.0。

任何人都可以解釋這一點嗎?

+0

我敢打賭'*&f'是一個引用類型。 – 2012-02-27 17:17:50

+0

賓果! std :: remove_reference <...>會訣竅! – smilingthax 2012-02-27 17:19:40

回答

13

需要注意的是decltype有兩個方面的含義是很重要的:它可以用來找到一個實體聲明的類型(因此它的名字),或者它可以被用來檢查一個表達。我在這裏鬆散地使用了實體,並沒有提及標準的任何術語,只是簡單地說它可能是一個變量,一個函數,或者(在我看來奇怪的是,一個成員訪問)。當檢查表達式時,返回的類型往往不是從表達式本身的類型不同,因此:

int i; 
void foo(); 
struct { int i; } t; 

static_assert(std::is_same<decltype(i),  int>::value,  ""); 
static_assert(std::is_same<decltype(foo), void()>::value, ""); 
static_assert(std::is_same<decltype(t.i), int>::value,  ""); 

static_assert(std::is_same<decltype((i)), int&>::value,  ""); 
static_assert(std::is_same<decltype((foo)), void(&)()>::value, ""); 
static_assert(std::is_same<decltype((t.i)), int&>::value,  ""); 

注意這是如何工作的功能,因此你的情況decltype(*&f)是一樣的如decltype((f)),而不是decltype(f)

+1

儘管Tgis是事實的一半。表達式(f)的類型不是引用類型。沒有表達是引用類型。 – 2012-02-27 19:20:54

+0

@ JohannesSchaub-litb你當然是對的。我不知道要放棄什麼類型的免責聲明 - 我認爲我的小小說不是簡化「decltype」的具體說明。然而,這是對價值類別,參考和參考類型如何相互作用的簡化。 – 2012-02-28 04:07:17

+0

@Potatoswatter我已經回滾了,因爲我設計了我的答案,沒有描述'decltype'的完整行爲。爲了回答這個問題,已經足夠(IMO)指出'decltype(name)'與'decltype((name))'是不同的。添加更多細節將更適合於關於'decltype'內部工作的問題。然而,我決定採用適當的免責聲明,指出這些片段只是爲了說明decltype行爲。 – 2012-02-28 09:15:27