2011-10-01 45 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 
}