decltype(auto) 有哪些用途? [英] What are some uses of decltype(auto)?

查看:40
本文介绍了decltype(auto) 有哪些用途?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 c++14 中引入了 decltype(auto) 习惯用法.

In c++14 the decltype(auto) idiom is introduced.

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

Typically its use is to allow auto declarations to use the decltype rules on the given expression.

搜索成语的好"用法示例,我只能想到以下内容(来自 Scott Meyers),即用于函数的返回类型推导:

Searching for examples of "good" usage of the idiom I can only think of things like the following (by Scott Meyers), namely for a function's return type deduction:

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

有没有其他例子证明这个新的语言功能很有用?

Are there any other examples where this new language feature is useful?

推荐答案

通用代码中的返回类型转发

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

Return type forwarding in generic code

For non-generic code, like the initial example you gave, you can manually select to get a reference as a return type:

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

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

but in generic code you want to be able to perfectly forward a return type without knowing whether you are dealing with a reference or a value. decltype(auto) gives you that ability:

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

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

在几天前的这个问答中,模板实例化过程中的无限递归当模板的返回类型被指定为 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) is used here to delay the return type deduction after the dust of template instantiation has settled.

您也可以在其他上下文中使用 decltype(auto),例如标准草案 N3936 还指出

You can also use decltype(auto) in other contexts, e.g. the draft Standard N3936 also states

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

1 autodecltype(auto) 类型说明符指定一个占位符稍后将被替换的类型,或者通过从初始值设定项或通过带有尾随返回类型的显式规范.auto 类型说明符也用于表示 lambda 是一个通用 lambda.

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 占位符类型可以与函数声明符一起出现在decl-specifier-seq、type-specifier-seq、转换函数 ID 或尾随返回类型,在此类声明符有效的任何上下文中.如果函数declarator 包含一个 trailing-return-type (8.3.5),它指定了函数的声明返回类型.如果函数声明的返回类型包含占位符类型,则函数的返回类型为从函数体中的 return 语句推导出来,如果有的话.

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.

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

The draft also contains this example of variable initialization:

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)

这篇关于decltype(auto) 有哪些用途?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆