c++ - C++11 decltype 的启发式用法

标签 c++ templates c++11 decltype

我刚刚看到 this really nice talk Rock Hard: C++ Evolving,作者 Boris Jabes。在关于高阶泛型编程的演讲部分中,他说以下是一个函数示例,该函数在返回类型方面更通用,并导致更少的模板函数重载

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

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

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

所以我猜这个例子并没有真的展示了 decltype 的独特力量。任何人都可以举一个例子来说明这种更启发 decltype 的用法吗?

最佳答案

你的怀疑是错误的。

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 的正确返回类型在过去的 C++ 中一直是一个具有挑战性的问题。现在这是一个简单的练习。

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

关于c++ - C++11 decltype 的启发式用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7623496/

相关文章:

c++ - C++ 类 std::numeric_limits 中的字段与方法

c++ - 开关语句使用

c++ - 候选模板被忽略 : could not match 'const type-parameter-0-0 *' against 'char'

c++ - 抽象线程相关的 STL 和 Boost 类型和方法

c++ - 除了移动语义之外,还有哪些 C++11 功能可以提高我的代码的性能?

c++ - 关于 "distinct addresses"的规则是否适用于 new 创建的对象?

c++ - QWebView 在 Ubuntu 13.10 上不工作

c++ - 在 win32 中调用 WM_PAINT 之间保留绘制的客户区域

java - 如何在 JMustache 中处理子模板中的 map 列表?

c++ - extern 模板是否会阻止函数内联?