一 含义

1.auto:作为一个占位符,用于表明存储类型,具体的类型由编译器根据auto表达式推导得出。

2.decltype:由编译器根据表达式返回其类型,不做编译时的类型推导。

二 auto典型代码

1.所有auto定义的变量或表达式必须初始化

auto ch = 'a';  // ch为char类型
auto x = 27; // x为int型
const auto cx = x; // cx为const int
const auto &rx = x; // rx为const it &
auto add_fun = [] (int x, int y) { return x + y; };

2.使用auto定义堆上的变量,必须初始化

//auto *p = 0;  // 编译错误
auto *p = new int(10);

3.auto仅仅是占位符,使用不会导致程序性能下降,但不能使用sizeof和typeid等取类型或者类型转换的操作符或函数

//sizeof(auto); // 编译错误
//typeid(auto); // 编译错误

4.C++17之前auto不能用于定义函数参数,模板,但C++17可以

// c++17编译通过
void fun(auto x) {
}
template <auto xxx>
void fun11() {
std::cout << xxx << std::endl;
}

5.使用auto &&定义变量时会根据左值或者右值来定

auto x = 27;
auto &&xx = x; // xx是int &
xx = 10; // 此时x变为10
const auto &cx = x;
auto &&yy = cx; // yy是const int &
//yy = 1; // 编译出错
auto &&zz = 100; // zz是int &&

6.使用auto作为函数返回值,需要“->”指明类型

auto fun() -> double {
return 1.0;
}

7.使用auto可定义数组指针或引用

char name[] = "hello modern c++";
auto pname = name; // pname是char *
pname[1] = 'a';
pname++;
auto &pname1 = name; // pname1是数组的引用
pname1[1] = 'b';
//pname1++; // 编译出错 数组引用即数组首地址 不能改变

8.使用auto定义{}被编译为std::initializer_list

auto xx = { 1, 2, 3 };  // xx为std::initializer_list<int>
//auto xx1 = { 1.1, 2, 3 }; // 编译出错 {}里类型不一致

9.在lambda表达式加入auto参数(C++14之和)

auto less_func = [] (const auto &p1, const auto &p2) { return *p1 < *p2 };
// 调用
less_func(std::unique_ptr<int>(new int (10)), std::unique_ptr<int>(new int (100)));

三 decltype典型代码

1.在函数模板中配合auto定义函数返回类型

template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}

template<typename T, typename U>
auto add(T &&t, U &&u) -> decltype(std::forward<T>(t) + std::forward<U>(u)) {
return std::forward<T>(t) + std::forward<U>(u);
}