c++ - decltype(auto) 有哪些用途?

标签 c++ auto c++14 decltype return-type-deduction

在 c++14 中引入了 decltype(auto) 成语。

通常它的用途是允许 auto 声明在给定表达式上使用 decltype 规则

搜索成语“良好”用法的示例我只能想到以下内容(通过 Scott Meyers ),即对于函数的返回类型推导:

template<typename ContainerType, typename IndexType>                // C++14
decltype(auto) grab(ContainerType&& container, IndexType&& index)
{
  authenticateUser();
  return std::forward<ContainerType>(container)[std::forward<IndexType>(index)];
}

还有其他例子可以说明这种新的语言功能有用吗?

最佳答案

泛型代码中的返回类型转发

对于非泛型代码,如您给出的初始示例,您可以手动选择获取引用作为返回类型:

auto const& Example(int const& i) 
{ 
    return i; 
}

但在通用代码中,您希望能够完美地转发返回类型,而无需知道您是在处理引用还是值。 decltype(auto)赋予你这种能力:

template<class Fun, class... Args>
decltype(auto) Example(Fun fun, Args&&... args) 
{ 
    return fun(std::forward<Args>(args)...); 
}

递归模板中延迟返回类型推导

this Q&A前几天在模板实例化过程中遇到了无限递归,当模板的返回类型指定为decltype(iter(Int<i-1>{}))时而不是 decltype(auto) .

template<int i> 
struct Int {};

constexpr auto iter(Int<0>) -> Int<0>;

template<int i>
constexpr auto iter(Int<i>) -> decltype(auto) 
{ return iter(Int<i-1>{}); }

int main() { decltype(iter(Int<10>{})) a; }

decltype(auto)此处用于延迟返回类型推导,待模板实例化尘埃落定。

其他用途

您也可以使用decltype(auto)在其他情况下,例如标准草案N3936还说

7.1.6.4 自动说明符 [dcl.spec.auto]

1 The auto and decltype(auto) type-specifiers designate a placeholder type that will be replaced later, either by deduction from an initializer or by explicit specification with a trailing-return-type. The auto type-specifier is also used to signify that a lambda is a generic lambda.

2 The placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid. If the function declarator includes a trailing-return-type (8.3.5), that specifies the declared return type of the function. If the declared return type of the function contains a placeholder type, the return type of the function is deduced from return statements in the body of the function, if any.

草案还包含这个变量初始化的例子:

int i;
int&& f();
auto x3a = i;                  // decltype(x3a) is int
decltype(auto) x3d = i;        // decltype(x3d) is int
auto x4a = (i);                // decltype(x4a) is int
decltype(auto) x4d = (i);      // decltype(x4d) is int&
auto x5a = f();                // decltype(x5a) is int
decltype(auto) x5d = f();      // decltype(x5d) is int&&
auto x6a = { 1, 2 };           // decltype(x6a) is std::initializer_list<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i;                // decltype(x7a) is int*
decltype(auto)*x7d = &i;       // error, declared type is not plain decltype(auto)

关于c++ - decltype(auto) 有哪些用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24109737/

相关文章:

c++ - main() 函数中的 try\catch block 没有括号

c++ - 如何使用自动变量选择迭代器类型?

c++ - 体系结构 x86_64 链接 constexpr std::array 的 undefined symbol

c++ - 关于矩阵计算,是否有 MATLAB 的快速且免费的替代方案?

c++ - 单元测试对实例变量函数的调用

c++ - Linux - 查找进程是否准备就绪或正在运行

c++ - 无法在 C++ 中通过自动迭代映射

c++ - 如何 SFINAE 启用返回 `auto` 的成员函数

c++ - 如何打印 n 维 C++ STL 容器?容器是数组的数组或 vector 的 vector

c++ - 保持对同一实例 C++ 的引用