int a = 1;
const int b = 1;
auto &x = a; // int &x
auto &y = b; // const int &y
auto &z = 1; // Ошибка, хотя `const int &z = 1` скомпилировалось бы.
const auto &w = 1; // const int &w
[const] [volatile] auto &&- 如果指定了至少一个 cv 限定符,则它与 类似auto &,但用于右值。
如果没有指定 cv-qualifiers,那么它就像一个转发链接:
MyClass a = 1;
const MyClass b = 1;
auto &&x = a; // MyClass &x
auto &&x = b; // const MyClass &x
auto &&x = MyClass(); // MyClass &&x
auto &&x = (const MyClass) MyClass(); // const MyClass &&x
[const] [volatile] auto &&, 以及auto, 可以与initializer_list:
auto &&x = {1,2,3}; // std::initializer_list<int> &&
const int n = 5;
auto m = n; // int
const int& p = n;
auto q = p; //int
const std::vector<int> v(1);
auto a = v[0]; // int
decltype(a) d ; // int, тип сущности, именованной как d
decltype(v[0]) b = 1; // const int& (возвращаемое значение
// std::vector<int>::operator[](size_type) const)
decltype((a)) ref = a; // int&, так как (a) является lvalue
auto value = ref; //int
++ref; // ошибка
++value; //правильно
推理规则与函数的规则非常相似,例如
template <typename T> void foo(T).[const] [volatile] auto- 永远不会是链接,不会自动添加 cv 限定符 (const,volatile)。一种特殊情况——如果这样的变量被初始化
= {a,b,c}——那么类型将是[const] [volatile] std::initializer_list<T>.[const] [volatile] auto &- 自动添加 cv 限定符(除非使用 rvalue 初始化它 - 然后不指定const它将是一个错误)。[const] [volatile] auto &&- 如果指定了至少一个 cv 限定符,则它与 类似auto &,但用于右值。如果没有指定 cv-qualifiers,那么它就像一个转发链接:
[const] [volatile] auto &&, 以及auto, 可以与initializer_list:在上述所有情况下,如果变量已初始化
{a}(不带=),则其auto行为与初始化器为 时的行为相同= a。花括号中必须只有一个元素。auto可以在更复杂的构造中引用:可以创建指向 的指针auto、指向成员的指针以及对它们的引用。指向指针的指针、指向函数的指针等是允许的。auto但是由于某种原因无法完成数组。如果您指向
auto,则会自动添加 cv 限定符:还有更多
decltype(auto)。它类似于auto,但不能被引用或指向,也不能被 cv 限定。它使用与 相同的推理规则
decltype。它特别适合编写函数包装器:
此处的返回类型
bar被复制到,foo即使它是一个引用。