启发C ++ 11 decltype的使用

时间:2011-10-01 23:00:10

标签: c++ templates c++11 decltype

我刚看过Boris Jabes的this really nice talk Rock Hard:C ++ Evolving 。在关于高阶通用编程的讨论部分中,他说以下是一个函数的例子,它的返回类型更通用,导致更少的模板函数重载

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

然而,这可以使用普通模板语法实现,如下所示

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

所以我猜选择的例子不会真正显示decltype的独特力量。任何人都可以举例说明decltype更多启发的用法吗?

3 个答案:

答案 0 :(得分:26)

您的怀疑不正确。

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);

在过去的C ++中,找出add的正确返回类型一直是一个具有挑战性的问题。现在这是一个简单的练习。

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

鲜为人知的是,你可以在decltype之前和伪析构函数名称中使用::

// 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 :(得分:1)

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

如果没有 decltype ,则无法自动调整容器 c 的value_type。

答案 2 :(得分:0)

我使用它的一个地方,就是我需要创建一个必须具有相同类型的另一个变量的变量。但我不确定将来这种类型是否会保持不变。

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