auto 关键字的含义是什么?
据我所知,auto
一直是一个奇怪的存储类说明符,没有任何用途。
但是,我已经尝试了 auto
的作用,并且它假定了我分配给它的任何类型! auto
使涉及迭代器和许多其他内容的代码更容易编写。
从什么时候开始可以使用这个关键字?它是 Visual C++ 扩展吗?
From what I've learned, auto
has always been a weird storage class specifier that didn't serve any purpose.
However, I've tried what auto
does, and it assumes the type of whatever I happen to assign to it!auto
makes code involving iterators and many other things much easier to write.
Since when can you use this keyword? Is it a Visual C++ extension?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
auto
是 C++ 从 C 中“继承”的一个关键字,它几乎一直存在,但实际上从未使用过,因为只有两种可能的情况:要么不允许,要么被假定为默认。使用
auto
来表示推导类型是 C++11 中的新功能。同时,
auto x =initializer
从initializer
的类型推导x
的类型,就像函数的模板类型推导一样模板。考虑这样的函数模板:在 A 点,已根据传递给
whatever
的参数值将类型分配给T
。当您执行auto x =initializer;
时,会使用相同的类型推导从用于的initializer
类型确定x
的类型初始化它。这意味着编译器实现 auto 所需的大多数类型推导机制已经存在,并用于任何尝试实现 C++98/03 的编译器上的模板。因此,对于几乎所有编译器团队来说,添加对 auto 的支持显然相当容易——添加得相当快,而且似乎也很少有与之相关的错误。
当这个答案最初写出来时(2011 年,在 C++ 11 标准墨迹未干之前),
auto
已经相当可移植了。如今,它在所有主流编译器中都是完全可移植的。避免它的唯一明显的原因是,如果您需要编写与 C 编译器兼容的代码,或者您有特定的需要针对某些您知道不支持它的利基编译器(例如,有些人仍然编写代码)对于使用 Borland、Watcom 等编译器的 MS-DOS,几十年来没有出现重大升级)。如果您使用的是任何主流编译器的最新版本,则完全没有理由避免它。该标准的最新修订添加了一些可以使用
auto
的新位置。从 C++14 开始,您可以使用auto
作为 lambda 的参数类型:这基本上与上面的示例执行相同的操作 - 尽管它没有显式使用
template
语法,这基本上是一个模板,它推断参数的类型,并在该类型上实例化模板。这非常方便且有用,在 C++20 中,为普通函数(而不仅仅是 lambda)添加了相同的功能。
但是,就像之前一样,所有这些实际上都归结为使用与自 C++98 以来的函数模板相同的基本类型推导机制。
auto
允许在更多地方、更方便地使用它,但底层的繁重工作保持不变。auto
was a keyword that C++ "inherited" from C that had been there nearly forever, but virtually never used because there were only two possible conditions: either it wasn't allowed, or else it was assumed by default.The use of
auto
to mean a deduced type was new with C++11.At the same time,
auto x = initializer
deduces the type ofx
from the type ofinitializer
the same way as template type deduction works for function templates. Consider a function template like this:At point A, a type has been assigned to
T
based on the value passed for the parameter towhatever
. When you doauto x = initializer;
, the same type deduction is used to determine the type forx
from the type ofinitializer
that's used to initialize it.This means that most of the type deduction mechanics a compiler needs to implement
auto
were already present and used for templates on any compiler that even sort of attempted to implement C++98/03. As such, adding support forauto
was apparently fairly easy for essentially all the compiler teams--it was added quite quickly, and there seem to have been few bugs related to it either.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.More recent revisions of the standard have added a few new places that
auto
can be used. Starting with C++14, you can useauto
for the type of a parameter to a lambda:This does essentially the same thing as the example above--even though it doesn't explicitly use
template
syntax, this is basically a template that deduces the type of the parameter, and instantiates the template over that type.That was convenient and useful enough that in C++20, the same capability was added for normal functions, not just lambdas.
But, just as before all of this really comes down to using the same basic type deduction mechanism as we've had for function templates since C++98.
auto
allows that to be used in more places, and more conveniently, but the underlying heavy lifting remains the same.它只是采用一个通常无用的关键字并赋予它一个新的、更好的功能。它是 C++11 中的标准,大多数支持 C++11 的 C++ 编译器都会支持它。
It's just taking a generally useless keyword and giving it a new, better functionality. It's standard in C++11, and most C++ compilers with even some C++11 support will support it.
对于变量,指定正在声明的变量的类型将从其初始值设定项自动推导。对于函数,指定返回类型是尾随返回类型或将从其返回语句推导出来 (C++14 起)。
语法
说明
在块作用域、命名空间作用域、for 循环的初始化语句等中声明变量时,可以使用关键字 auto 作为类型说明符。
一旦确定了初始值设定项的类型,编译器就会使用函数调用中的模板参数推导规则来确定将替换关键字 auto 的类型(有关详细信息,请参阅模板参数推导#其他上下文)。关键字 auto 可能会附带修饰符,例如 const 或 &,这些修饰符将参与类型推导。例如,给定 const auto& i = expr;,i的类型正是假想模板
template中参数u的类型void f(const U& u)
如果函数调用f(expr)
已编译。因此,汽车&&可以根据初始化器推导为左值引用或右值引用,用于基于范围的 for 循环。如果使用 auto 声明多个变量,则推导的类型必须匹配。例如,声明
auto i = 0, d = 0.0;
格式错误,而声明auto i = 0, *p = &i;
格式良好-formed 并且 auto 被推导为 int。在使用尾随返回类型语法的函数声明中,关键字 auto 不执行自动类型检测。它仅作为语法的一部分。
在不使用尾随返回类型语法的函数声明中,关键字 auto 指示将使用模板参数推导规则从其 return 语句的操作数推导返回类型。
如果变量的声明类型为
decltype(auto)
,则关键字auto将被替换为其初始值设定项的表达式(或表达式列表),并使用以下规则推导出实际类型decltype。如果函数的返回类型被声明为
decltype(auto)
,则关键字auto将被其return语句的操作数替换,并使用decltype的规则推导出实际的返回类型。形式为 auto:: 的嵌套名称说明符是一个占位符,它被替换为遵循约束类型占位符推导规则的类或枚举类型。
lambda 表达式中的参数声明。 (C++14 起) 函数参数声明。 (概念 TS)
注释
在 C++11 之前,auto 具有存储持续时间说明符的语义。
在一个声明中混合自动变量和函数,如 auto f() -> int, i = 0; 是不允许的。
欲了解更多信息: http://en.cppreference.com/w/cpp/language/auto
For variables, specifies that the type of the variable that is being declared will be automatically deduced from its initializer. For functions, specifies that the return type is a trailing return type or will be deduced from its return statements (since C++14).
Syntax
Explanation
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 templatetemplate<class U> void f(const U& u)
if the function callf(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 declarationauto 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)
Notes
Until C++11, auto had the semantic of a storage duration specifier.
Mixing auto variables and functions in one declaration, as in
auto f() -> int, i = 0;
is not allowed.For more info : http://en.cppreference.com/w/cpp/language/auto
auto关键字是C++中一个重要且经常使用的关键字。在初始化变量时,auto关键字用于类型推断(也称为类型推导)。
关于 auto 关键字有 3 种不同的规则。
第一条规则
auto x = expr;
---->没有指针或引用,只有变量名。在这种情况下,const 和引用将被忽略。第二条规则
auto& y = expr;
或auto* y = expr; ---->
----> auto 关键字后的引用或指针。警告:此规则中不会忽略 const ! 。
警告:在此规则中,不会发生数组到指针的转换(数组衰减)!
第三条规则
auto&& z = expr;
---->这不是右值引用。警告:如果类型推断有问题并且 &&使用令牌,名称
像这样引入的称为“转发参考”(也称为通用参考)。
The auto keyword is an important and frequently used keyword for C ++.When initializing a variable, auto keyword is used for type inference(also called type deduction).
There are 3 different rules regarding the auto keyword.
First Rule
auto x = expr;
----> No pointer or reference, only variable name. In this case, const and reference are ignored.Second Rule
auto& y = expr;
orauto* y = expr;
----> Reference or pointer after auto keyword.Warning : const is not ignored in this rule !!! .
Warning : In this rule, array to pointer conversion (array decay) does not occur !!!.
Third Rule
auto&& z = expr;
----> This is not a Rvalue reference.Warning : If the type inference is in question and the && token is used, the names
introduced like this are called "Forwarding Reference" (also called Universal Reference).
这个功能在你的一生中都没有出现过。自 2010 版本起,Visual Studio 就开始支持它。这是一个新的 C++11 功能,因此它不是 Visual Studio 独有的,并且是/将是可移植的。大多数编译器已经支持它。
This functionality hasn't been there your whole life. It's been supported in Visual Studio since the 2010 version. It's a new C++11 feature, so it's not exclusive to Visual Studio and is/will be portable. Most compilers support it already.
auto 关键字指定将自动从其初始值设定项中扣除正在声明的变量的类型。对于函数,如果它们的返回类型是 auto,那么它将在运行时通过返回类型表达式进行计算。
当我们必须使用迭代器时它非常有用。例如,对于下面的代码,我们可以简单地使用“auto”,而不是编写整个迭代器语法。
这就是我们如何使用“auto”关键字
The auto keyword specifies that the type of the variable that is being declared will be automatically deducted from its initializer. In case of functions, if their return type is auto then that will be evaluated by return type expression at runtime.
It can be very useful when we have to use the iterator. For e.g. for below code we can simply use the "auto" instead of writing the whole iterator syntax .
This is how we can use "auto" keyword
它不会去任何地方......它是 C++11 实现中的一个新的标准 C++ 功能。话虽这么说,虽然它是简化对象声明以及清理某些调用范式(即基于范围的 for 循环)的语法的绝佳工具,但不要过度使用/滥用它:-)
It's not going anywhere ... it's a new standard C++ feature in the implementation of C++11. That being said, while it's a wonderful tool for simplifying object declarations as well as cleaning up the syntax for certain call-paradigms (i.e., range-based for-loops), don't over-use/abuse it :-)
它的神奇之处在于它能够减少为传递到特定函数的每个变量类型编写代码的必要性。考虑在 C 语言基础上有一个与 Python 类似的 print() 函数。
It's Magic is it's ability to reduce having to write code for every Variable Type passed into specific functions. Consider a Python similar print() function in it's C base.