# auto 与 decltype

URL: https://caijiao.org/cpp/stl/auto
Source: docs/cpp/stl/auto.md
Description: 本节介绍 C++ 中的 'auto' 和 'decltype' 关键字，帮助理解它们的用途，如何自动推导类型以及如何推导表达式的类型。

在 C++11 中，`auto` 和 `decltype` 是两个非常有用的关键字，用于自动推导变量的类型和表达式的类型。这两者能够简化代码，提高开发效率，尤其是在处理复杂类型时非常有用。

## auto

`auto` 是 C++11 引入的一个关键字，它允许编译器根据初始化表达式的类型自动推导变量的类型。使用 `auto` 可以避免显式声明变量的类型，特别是当类型较为复杂时，能够大大简化代码。

### 使用 auto 的基本语法

```cpp
auto variable_name = expression;
````

### 示例：使用 auto 推导类型

```cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};

    // auto 推导为 vector<int>::iterator 类型
    auto it = v.begin();
    
    cout << *it << endl;  // 输出 1

    return 0;
}
```

在此例中，`auto it = v.begin();`，编译器会自动推导 `it` 的类型为 `vector<int>::iterator`。

### auto 与 const 修饰符

`auto` 可以与 `const` 一起使用来指定常量值。需要注意的是，`auto` 不会推导为引用类型，除非显式指定。

### 示例：使用 auto 和 const

```cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};

    // auto 和 const 配合使用
    const auto value = v[0];  // value 类型为 const int
    
    cout << value << endl;  // 输出 1

    return 0;
}
```

在此例中，`auto` 会根据 `v[0]` 的类型推导为 `int`，并且因为使用了 `const`，`value` 的类型变为 `const int`。

## decltype

`decltype` 是 C++11 引入的另一个关键字，它用于获取表达式的类型，通常用于推导出复杂表达式的类型。在某些情况下，`decltype` 比 `auto` 更强大，因为它可以推导变量或表达式的确切类型，甚至包括引用和常量。

### 使用 decltype 的基本语法

```cpp
decltype(expression) variable_name;
```

### 示例：使用 decltype 获取类型

```cpp
#include <iostream>

using namespace std;

int main() {
    int x = 5;
    double y = 3.14;
    
    // 使用 decltype 获取变量类型
    decltype(x) a = 10;  // a 的类型为 int
    decltype(y) b = 2.71;  // b 的类型为 double

    cout << "a: " << a << ", b: " << b << endl;  // 输出 a: 10, b: 2.71

    return 0;
}
```

在此例中，`decltype(x)` 会推导出 `x` 的类型 `int`，而 `decltype(y)` 会推导出 `y` 的类型 `double`。

### decltype 和引用

`decltype` 会保留表达式的引用类型，意味着如果被 `decltype` 推导的类型是引用类型，`decltype` 会返回一个引用类型。

### 示例：decltype 与引用

```cpp
#include <iostream>

using namespace std;

int main() {
    int x = 5;
    int& y = x;

    decltype(x) a = 10;  // a 的类型为 int
    decltype(y) b = x;   // b 的类型为 int&，引用类型
    
    cout << "a: " << a << ", b: " << b << endl;  // 输出 a: 10, b: 5

    return 0;
}
```

在此例中，`decltype(x)` 返回 `int` 类型，而 `decltype(y)` 返回 `int&` 类型，因为 `y` 是 `x` 的引用。

### 使用 decltype 和 auto 配合

有时，我们可能会希望同时使用 `auto` 和 `decltype`，例如，在声明函数返回类型时，或者处理复杂类型时。

### 示例：auto 与 decltype 配合使用

```cpp
#include <iostream>
#include <vector>

using namespace std;

auto add(int a, int b) -> decltype(a + b) {  // 使用 decltype 推导返回值类型
    return a + b;
}

int main() {
    int result = add(5, 3);  // result 的类型由 decltype(a + b) 推导为 int
    cout << result << endl;  // 输出 8

    return 0;
}
```

在此例中，`auto add(int a, int b) -> decltype(a + b)` 表明函数的返回类型是 `a + b` 的类型。

## 总结

* `auto` 用于自动推导变量类型，简化了声明，尤其适合复杂类型。
* `decltype` 用于获取表达式的类型，通常比 `auto` 更强大，特别是在需要精确获取类型时。
* `auto` 可以和 `const` 或引用一起使用，而 `decltype` 会保留表达式的引用类型。

`auto` 和 `decltype` 在 C++ 中极大地增强了类型推导的能力，使代码更加简洁和灵活。
