2011-10-01 69 views
11

我剛纔看到this really nice talkRock Hard:C++ Evolving作者:Boris Jabes。在關於高階泛型編程談話的部分他說,下面是一個函數,是關於它的返回類型更通用的例子,並導致更少的模板函數重載C++ 11 decltype的啓發性用法

template <typename Func> 
auto deduce(const Func & f) -> decltype(f()) 
{..} 

這然而,可以使用普通的模板語法如下

template <typename Func> 
Func deduce(const Func & f) 
{..} 

,所以我想選擇不真正展現decltype的獨特的電源的例子來實現。任何人都可以舉一個這樣的例子嗎啓發使用decltype

+7

號的第一個例子是指'''推斷(F)'''返回'''Func'''的結果的類型。第二個例子意味着'''推斷(f)'''返回'''Func'''。你看得到差別嗎? –

+0

啊,對不起,我錯過了'decltype'參數內的額外'()'。我的錯。 –

回答

25

您的懷疑是不正確的。

void f() { } 

現在deduce(&f)具有類型void,但與你的改寫,它的類型是void(*)()。在任何情況下,無論你想獲得表達式還是聲明類型,都可以使用decltype(注意這兩者之間的細微差別,decltype(x)不一定與decltype((x))相同)。

例如,很可能你的標準庫實現某處包含像

using size_t = decltype(sizeof(0)); 
using ptrdiff_t = decltype((int*)0 - (int*)0); 
using nullptr_t = decltype(nullptr); 

線找出的add正確的返回類型一直貫穿過去℃的具有挑戰性的問題++。這現在是一個簡單的練習。

template<typename A, typename B> 
auto add(A const& a, B const& b) -> decltype(a + b) { return a + b; } 

鮮爲人知的是,你可以::之前和僞析構函數名

// has no effect 
(0).~decltype(0)(); 

// it and ite will be iterators into an initializer list 
auto x = { 1, 2, 3 }; 
decltype(x)::iterator it = x.begin(), ite = x.end(); 
+1

您能否解釋一下這個問題:'(0)。〜decltype(0)();'?恐怕我不明白。 –

1
std::for_each(c.begin(), c.end(), [](decltype (c.front()) val){val*=2;}); 

Autodeducting容器Ç的VALUE_TYPE離不開decltype來完成。

+1

只有當你使用lambdas時,它不能被完成,因爲它們不是多態的(但是,我們希望它們在C++ y中)。如果您使用的是多態函數對象,則會自動推導出它。 –

0

一個地方,我用它使用decltype,是我需要做的是必須有相同類型的變量另一個變量。但我不確定未來的類型是否會保持不變。

void foo(int a)//maybe in future type of a changed 
{ 
    decltype(a) b; 
    //do something with b 
} 
相關問題