美文网首页C++ 11
004 auto 类型说明符

004 auto 类型说明符

作者: 赵者也 | 来源:发表于2020-02-03 09:49 被阅读0次

auto 让编译器通过初始值来推算变量的类型。显然,auto 定义的变量必须有初始值:

auto item = val1 + val2;  // item 初始化为 val1 和 val2 相加的结果

使用 auto 也能在一条语句中声明多个变量。因为一条声明语句只能有一个基本数据类型:

auto i = 0, *p = &i;  // 正确:i 是整数、p 是整型指针
auto sz = 0, pi = 3.14;  // 错误:sz 和 pi 的类型不一致

** 复合类型、常量和 auto**

int i = 0, &r = i;
auto b = r;  // 编译器以引用对象的类型作为 auto 的类型

auto 一般会忽略掉顶层 const,同时底层 const 则会保留下来,比如当初始值是一个指向常量的指针时:

int i = 0;
const int ci = i, &cr = ci;
auto b = ci;    // b 是一个整数(ci 的顶层 const 特性被忽略)
auto c = cr;    // c 是一个整数(cr 是 ci 的别名,ci 本身是一个顶层 const)
auto d = &i;    // d 是一个整型指针(整数的地址就是指向整数的指针)
auto e = &ci;   // e 是一个指向整数常量的指针(对常量对象取地址是一种底层 const)

如果希望推断出的 auto 类型是一个顶层 const,需要明确指出:

const auto f = ci;  // f 是 const int

还可以将引用的类型设为 auto,此时原来的初始化规则仍然适用:

auto &g = ci;   // g 是一个整型常量引用,绑定到 ci
//auto &h = 42;   // 错误:不能为非常量引用绑定字面值
const auto &j = 42; // 正确:为常量引用绑定字面值

设置一个类型为 auto 的引用时,初始值中的顶层常量属性仍然保留。和往常一样,如果我们给初始值绑定一个引用,则此时的常量就不是顶层常量了。
要在一条语句中定义多个变量,切记,符号 & 和 * 只从属于某个声明符,而非基本数据类型的一部分,因此初始值必须是同一种类型:

auto k = ci, &l = i; // k 是整数,l 是整型引用
auto &m = ci, *p = &ci; // m 是对整型常量的引用,p 是指向整型常量的指针
//auto &n = i, *p2 = &ci; // 错误:i 的类型是 int 而 &ci 的类型是 const int

上述内容的测试代码如下:

#include <QCoreApplication>
#include <cxxabi.h>
#include <QDebug>
#include <typeinfo>
#include <iostream>
#include <string>
#include <memory>
#include <cstdlib>

namespace  {

std::string demangle(const char* mangled)
{
      int status;
      std::unique_ptr<char[], void (*)(void*)> result(
        abi::__cxa_demangle(mangled, nullptr, nullptr, &status), std::free);
      return result.get() ? std::string(result.get()) : "error occurred";
}

template<class T>
void foo(T t) { std::cout << demangle(typeid(t).name()) << std::endl; }

}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    int i = 0;
    const int ci = i, &cr = ci;
    auto b = ci;    // b 是一个整数(ci 的顶层 const 特性被忽略)
    auto c = cr;    // c 是一个整数(cr 是 ci 的别名,ci 本身是一个顶层 const)
    auto d = &i;    // d 是一个整型指针(整数的地址就是指向整数的指针)
    auto e = &ci;   // e 是一个指向整数常量的指针(对常量对象取地址是一种底层 const)

    const auto f = ci;  // f 是 const int

    auto &g = ci;   // g 是一个整型常量引用,绑定到 ci
//    auto &h = 42;   // 错误:不能为非常量引用绑定字面值
    const auto &j = 42; // 正确:为常量引用绑定字面值

    auto k = ci, &l = i; // k 是整数,l 是整型引用
    auto &m = ci, *p = &ci; // m 是对整型常量的引用,p 是指向整型常量的指针
//    auto &n = i, *p2 = &ci; // 错误:i 的类型是 int 而 &ci 的类型是 const int

    foo(b);
    foo(c);
    foo(d);
    foo(e);
    foo(f);
    foo(g);
    foo(j);
    foo(k);
    foo(l);
    foo(m);
    foo(p);

    return a.exec();
}

测试代码的输出结果如下:

int
int
int*
int const*
int
int
int
int
int
int
int const*

用于初始化

如果我们提供了一个括号包围的初始化器,就可以使用 auto 从此初始化器来推断我们想要分配的对象的类型。但是,由于编译器要用初始化器的类型来推断要分配的类型,只有当括号中仅有单一初始化器时才可以使用 auto:

auto p1 = new auto(obj); // p1 指向一个与 obj 类型相同的对象,该对象用 obj 进行初始化
auto p2 = new auto{a,b,c}; // 错误:括号中只能有单个初始化器

p1 的类型是一个指针,指向从 obj 自动推断出的类型。若 obj 是一个 int,那么 p1 就是 int;若 obj 是一个 string,那么 p1 是一个 string;依此类推。新分配的对象用 obj 的值进行初始化。

相关文章

  • 004 auto 类型说明符

    auto 让编译器通过初始值来推算变量的类型。显然,auto 定义的变量必须有初始值: 使用 auto 也能在一条...

  • 关于变量的定义

    变量的定义和声明格式: 【存储类型说明符】_【类型限定值】_类型名称_变量列表; 存储类型说明符: auto:自动...

  • 存储类型说明符

    C语言中的存储类型说明符 typedef extern static auto register __block说...

  • c++ primer 阅读 day4

    2.5.2 auto 类型说明符 可以从表达式推断出要定义变量的类型, 编译器是将引用的对象的类型作为auto的类...

  • auto && decltype

    auto:C++11标准引入的类型说明符,编译器通过初始值来推算变量的类型。因此,auto定义的变量必须有初始值a...

  • [c] 存储类别说明符

    [ C Primer Plus ]--笔记 c语言有6个关键字作为存储类别说明符: 注意 : auto 说明符:表...

  • Day06

    类型说明符 长度说明符注意点: 书写长度说明符号可以省略int 符号说明符注意点: 如果被变量unsigned修饰...

  • 类型说明符

    类型说明符 类型说明符:说明长度的(可以用于修改类型所占用的存储空间的大小)short等于short int 占用...

  • const限定符和auto类型说明符

    const限定符 1.限定常量 有时我们希望定义这样的变量:它的值不能被改变。为了满足这一要求,我们使用const...

  • C++中的const、static和extern

    1. const 常量变量const 类型说明符 变量名 常引用const 类型说明符 &引用名 常对象类名 co...

网友评论

    本文标题:004 auto 类型说明符

    本文链接:https://www.haomeiwen.com/subject/yrlveqtx.html