从我用来学习c++的所有材料来看,auto一直是一个奇怪的存储持续时间指示符,没有任何用处。但就在最近,我遇到了一些代码,它们将它本身用作类型名。出于好奇,我尝试了一下,它假设我分配给它的任何类型!

突然间,STL迭代器,以及任何使用模板的东西都变得容易了10倍。感觉我在使用一种“有趣”的语言,比如Python。

这个关键字在我的生活中哪里呢?你会说这是visual studio独有的或者不能携带的,这会让我的梦想破灭吗?


当前回答

auto是c++从C“继承”来的一个关键字,它几乎一直存在,但实际上从未被使用过,因为只有两种可能的情况:要么它不被允许,要么它是默认的。

使用auto来表示演绎的类型是c++ 11中新出现的。

同时,auto x = initializer从初始化式的类型中推断x的类型,这与模板类型推断函数模板的工作方式相同。考虑这样一个函数模板:

template<class T>
int whatever(T t) { 
    // point A
};

在点A,一个类型已经根据传递给参数的值赋给了T。当您执行auto x = initializer;时,将使用相同的类型推断,从用于初始化x的初始化式的类型中确定x的类型。

这意味着编译器实现auto所需的大多数类型推断机制已经存在,并且用于任何试图实现c++ 98/03的编译器的模板。因此,对所有编译器团队来说,添加对auto的支持显然是相当容易的——它的添加速度非常快,而且似乎也几乎没有与之相关的错误。

When this answer was originally written (in 2011, before the ink was dry on the C++ 11 standard) auto was already quite portable. Nowadays, it's thoroughly portable among all the mainstream compilers. The only obvious reasons to avoid it would be if you need to write code that's compatible with a C compiler, or you have a specific need to target some niche compiler that you know doesn't support it (e.g., a few people still write code for MS-DOS using compilers from Borland, Watcom, etc., that haven't seen significant upgrades in decades). If you're using a reasonably current version of any of the mainstream compilers, there's no reason to avoid it at all though.

该标准最近的修订增加了一些可以使用auto的新地方。从c++ 14开始,你可以使用auto作为lambda的形参类型:

    [](auto s) { return s + 1; }

这在本质上与上面的示例所做的事情相同——尽管它没有显式地使用模板语法,但这基本上是一个推断形参类型的模板,并根据该类型实例化模板。

这是非常方便和有用的,以至于在c++ 20中,为普通函数添加了相同的功能,而不仅仅是lambdas。

但是,就像之前一样,所有这些都归结为使用与c++ 98以来的函数模板相同的基本类型推断机制。Auto允许在更多的地方使用,更方便,但底层的繁重工作保持不变。

其他回答

auto关键字指定要声明的变量的类型将自动从其初始化式中扣除。对于函数,如果它们的返回类型是auto,那么将在运行时由返回类型表达式计算。

当我们必须使用迭代器时,它会非常有用。例如,对于下面的代码,我们可以简单地使用“auto”,而不是编写整个迭代器语法。

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

这就是我们如何使用“auto”关键字

它只是采用一个通常无用的关键字,并赋予它一个新的、更好的功能。它是c++ 11中的标准,大多数c++编译器甚至有一些c++ 11支持都会支持它。

这种功能并不是你一生中就有的。自2010年版本以来,Visual Studio一直支持它。它是c++ 11的一个新特性,所以它不是Visual Studio独有的,并且是可移植的。大多数编译器已经支持它了。

auto关键字是c++中一个重要且常用的关键字。在初始化变量时,auto关键字用于类型推断(也称为类型推断)。

关于auto关键字有3条不同的规则。

第一条规则

Auto x = expr;---->没有指针或引用,只有变量名。在这种情况下,const和reference将被忽略。

int  y = 10;
int& r = y;
auto x = r; // The type of variable x is int. (Reference Ignored)

const int y = 10;
auto x = y; // The type of variable x is int. (Const Ignored)

int y = 10;
const int& r = y;
auto x = r; // The type of variable x is int. (Both const and reference Ignored)

const int a[10] = {};
auto x = a; //  x is const int *. (Array to pointer conversion)

Note : When the name defined by auto is given a value with the name of a function,
       the type inference will be done as a function pointer.

第二条规则

Auto& y = expr;或auto* y = expr;----> auto关键字后的引用或指针。

警告:const在此规则中不会被忽略!!.

int y = 10;
auto& x = y; // The type of variable x is int&.

警告:在此规则中,数组到指针的转换(数组衰减)不会发生!!

auto& x = "hello"; // The type of variable x is  const char [6].

static int x = 10;
auto y = x; // The variable y is not static.Because the static keyword is not a type. specifier 
            // The type of variable x is int.

第三条规则

Auto&& z = expr;---->不是右值引用。

警告:如果存在类型推断问题,并且使用了&&标记,则名称 像这样引入的被称为“转发引用”(也称为通用引用)。

auto&& r1 = x; // The type of variable r1 is int&.Because x is Lvalue expression. 

auto&& r2 = x+y; // The type of variable r2 is int&&.Because x+y is PRvalue expression. 

对于变量,指定要声明的变量的类型将自动从其初始化式推导出来。对于函数,指定返回类型是尾随返回类型或将从其返回语句中推导出(自c++ 14起)。

语法

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

解释

When declaring variables in block scope, in namespace scope, in initialization statements of for loops, etc., the keyword auto may be used as the type specifier. Once the type of the initializer has been determined, the compiler determines the type that will replace the keyword auto using the rules for template argument deduction from a function call (see template argument deduction#Other contexts for details). The keyword auto may be accompanied by modifiers, such as const or &, which will participate in the type deduction. For example, given const auto& i = expr;, the type of i is exactly the type of the argument u in an imaginary template template<class U> void f(const U& u) if the function call f(expr) was compiled. Therefore, auto&& may be deduced either as an lvalue reference or rvalue reference according to the initializer, which is used in range-based for loop. If auto is used to declare multiple variables, the deduced types must match. For example, the declaration auto i = 0, d = 0.0; is ill-formed, while the declaration auto i = 0, *p = &i; is well-formed and the auto is deduced as int. In a function declaration that uses the trailing return type syntax, the keyword auto does not perform automatic type detection. It only serves as a part of the syntax. In a function declaration that does not use the trailing return type syntax, the keyword auto indicates that the return type will be deduced from the operand of its return statement using the rules for template argument deduction. If the declared type of the variable is decltype(auto), the keyword auto is replaced with the expression (or expression list) of its initializer, and the actual type is deduced using the rules for decltype. If the return type of the function is declared decltype(auto), the keyword auto is replaced with the operand of its return statement, and the actual return type is deduced using the rules for decltype. A nested-name-specifier of the form auto:: is a placeholder that is replaced by a class or enumeration type following the rules for constrained type placeholder deduction. A parameter declaration in a lambda expression. (since C++14) A function parameter declaration. (concepts TS)

笔记

在c++ 11之前,auto具有存储持续时间说明符的语义。 将auto变量和函数混合在一个声明中,如auto f() -> int, i = 0;是不允许的。

欲了解更多信息:http://en.cppreference.com/w/cpp/language/auto