我刚看过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
更多启发的用法吗?
答案 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
}