auto 指定符

1) 在块作用域、命名空间作用域、循环初始化语句等中声明变量时,关键词  auto 可用作类型指定符。

只要初始化器的类型被确定,则编译器会用来自函数调用的模板实参推导规则所决定的类型替换关键词 auto (细节见模板实参推导)。关键词 auto 可与修饰符组合,如 const 或 & ,它们将参与类型推导。例如,给出 const auto& i = expr; , i 的类型恰是虚构模板 template<class U> void f(const U& u) 中参数 u 的类型,倘若函数调用 f(expr) 被编译。从而, auto&& 可根据初始化器被推导成左值或是右值引用,这被用于基于范围的for循环。

若  auto 被用于声明多个变量,则推导类型必须相符。例如,声明  auto i = 0, d = 0.0; 为病式,而声明  auto i = 0*= &i; 为良式,这里  auto 被推导成 int
2) 在使用尾随返回类型语法的 函数声明中,关键词  auto 不进行自动类型检测。它只作为语法的一部分起作用。
3) 在不使用尾随返回类型语法的 函数声明中,关键词  auto 指示返回类型将通过其  return 语句的运算数,用 模板实参推导规则推导出。
4) 若变量的声明类型是  decltype(auto) ,则关键词  auto 被替换成其初始化器的表达式(或表达式列表),而实际类型以  decltype 规则推导。
5) 若函数返回值的声明类型为  decltype(auto) ,则关键词  auto 被替换成其返回语句的运算数,而其实际返回类型以  decltype 规则推导。
6) 拥有形式  auto:: 的嵌套名称指定符是占位符,它会被类或枚举类型遵循 制约类型占位符推导规则替换。
7)  lambda 表达式中的参数声明。 (C++14 起) 函数参数声明。 (概念 TS)
8) 若 模板形参声明为  auto ,则其类型由对应使用参数推导出。

注意

C++11 前, auto 拥有存储期指定符的语义。

不允许在一个声明中混合 auto 变量和函数,如 auto f() -> int, i = 0; 。

示例

#include <iostream>
#include <utility>
 
template<class T, class U>
auto add(T t, U u) { return t + u; } // 返回类型是 operator+(T, U) 的类型
 
// 在其所调用的函数返回引用的情况下
// 函数调用的完美转发必须用 decltype(auto)
template<class F, class... Args>
decltype(auto) PerfectForward(F fun, Args&&... args) 
{ 
    return fun(std::forward<Args>(args)...); 
}
 
template<auto n> // C++17 auto 形参声明
auto f() -> std::pair<decltype(n), decltype(n)> // auto 不能从花括号初始化器列表推导
{
    return {n, n};
}
 
int main()
{
    auto a = 1 + 2;            // a 的类型是 int
    auto b = add(1, 1.2);      // b 的类型是 double
    static_assert(std::is_same_v<decltype(a), int>);
    static_assert(std::is_same_v<decltype(b), double>);
 
    decltype(auto) c1 = a;   // c1 的类型是 int ,保有 a 的副本
    decltype(auto) c2 = (a); // c2 的类型是 int& ,为 a 的别名
    std::cout << "a, before modification through c2 = " << a << '\n';
    ++c2;
    std::cout << "a, after modification through c2 = " << a << '\n';
 
    auto [v, w] = f<0>(); // 结构化绑定声明
 
    auto d = {1, 2}; // OK : d 的类型是 std::initializer_list<int>
    auto n = {5};    // OK : n 的类型是 std::initializer_list<int>
//  auto e{1, 2};    // C++17 起错误,之前为 std::initializer_list<int>
    auto m{5};       // OK : C++17 起 m 的类型为 int ,之前为 initializer_list<int>
//  decltype(auto) z = { 1, 2 } // 错误: {1, 2} 不是表达式
 
    // auto 常用于无名类型,例如 lambda 表达式的类型
    auto lambda = [](int x) { return x + 3; };
 
//  auto int x; // 于 C++98 合法, C++11 起错误
//  auto x;     // 于 C 合法,于 C++ 错误
}

可能的输出:

a, before modification through c2 = 3
a, after modification through c2 = 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值