C++ auto 关键字。为什么是魔法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7576953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ auto keyword. Why is it magic?
提问by Anne Quinn
From all the material I used to learn C++, auto
has always been a weird storage duration specifier that didn't serve any purpose. But just recently, I encountered code that used it as a type name in and of itself. Out of curiosity I tried it, and it assumes the type of whatever I happen to assign to it!
从我用来学习 C++ 的所有材料来看,auto
一直是一个奇怪的存储持续时间说明符,没有任何用途。但就在最近,我遇到了将其用作类型名称的代码。出于好奇,我尝试了它,它假定我碰巧分配给它的任何类型!
Suddenly STL iterators and, well, anything at all that uses templates is 10 fold easier to write. It feels like I'm using a 'fun' language like Python.
突然间,STL 迭代器以及任何使用模板的东西都变得更容易编写 10 倍。感觉就像我在使用一种“有趣”的语言,比如 Python。
Where has this keyword been my whole life? Will you dash my dreams by saying it's exclusive to visual studio or not portable?
这个关键词一直在我的生活中在哪里?你会说它是visual studio独有的还是不可移植的,这会打破我的梦想吗?
回答by Jerry Coffin
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.
auto
是 C++ 从 C “继承”的关键字,它几乎永远存在,但实际上从未使用过,因为只有两种可能的条件:要么不允许,要么默认情况下假定。
The use of auto
to mean a deduced type was new with C++11.
使用auto
表示推导类型是 C++11 的新功能。
At the same time, auto x = initializer
deduces the type of x
from the type of initializer
the same way as template type deduction works for function templates. Consider a function template like this:
同时auto x = initializer
,x
从类型推导的类型initializer
与模板类型推导对函数模板的工作方式相同。考虑这样的函数模板:
template<class T>
int whatever(T t) {
// point A
};
At point A, a type has been assigned to T
based on the value passed for the parameter to whatever
. When you do auto x = initializer;
, the same type deduction is used to determine the type for x
from the type of initializer
that's used to initialize it.
在 A 点,T
根据传递给 的参数值分配了一个类型whatever
。当你这样做时auto x = initializer;
,相同的类型推导用于x
从initializer
用于初始化它的类型来确定类型。
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 for auto
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.
这意味着编译器需要实现的大多数类型推导机制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.
最初编写此答案时(在 2011 年,在 C++ 11 标准上墨水未干之前)auto
已经非常便携。如今,它在所有主流编译器之间完全可移植。避免它的唯一明显原因是,如果您需要编写与 C 编译器兼容的代码,或者您有特定的需要针对某些您知道不支持它的小众编译器(例如,一些人仍在编写代码适用于使用 Borland、Watcom 等编译器的 MS-DOS,这些编译器几十年来没有进行过重大升级)。如果您使用的是任何主流编译器的合理当前版本,则完全没有理由避免使用它。
回答by Nicol Bolas
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++11 中的标准,大多数甚至支持 C++11 的 C++ 编译器都会支持它。
回答by R. Martinho Fernandes
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.
这个功能在你的一生中并没有出现。自 2010 版本以来,它在 Visual Studio 中得到支持。这是一个新的 C++11 功能,因此它不是 Visual Studio 独有的,并且是/将是可移植的。大多数编译器已经支持它。
回答by Prathamesh Aware
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).
对于变量,指定正在声明的变量的类型将从其初始值设定项中自动推导出。对于函数,指定返回类型是尾随返回类型或将从其返回语句中推导出 (C++14 起)。
Syntax
句法
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)
Explanation
解释
1) 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.
1) 在块作用域、命名空间作用域、for 循环的初始化语句等中声明变量时,可以使用关键字auto 作为类型说明符。一旦确定了初始化器的类型,编译器就会使用从函数调用中推导模板参数的规则来确定将替换关键字 auto 的类型(有关详细信息,请参阅模板参数推导#Other contexts)。关键字 auto 可能带有修饰符,例如 const 或 &,它们将参与类型推导。例如,给定const auto& i = expr;
,i的类型是完全自变量的u中的假想模板的类型template<class U> void f(const U& u)
,如果函数调用f(expr)
被编译。因此,根据初始值设定项,可以将 auto&& 推导出为左值引用或右值引用,这在基于范围的 for 循环中使用。如果 auto 用于声明多个变量,则推导的类型必须匹配。例如,auto i = 0, d = 0.0;
声明auto i = 0, *p = &i;
是格式错误的,而声明是格式良好的,而 auto 被推导出为 int。
2) 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.
2) 在使用尾随返回类型语法的函数声明中,关键字 auto 不执行自动类型检测。它仅作为语法的一部分。
3) 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.
3) 在不使用尾随返回类型语法的函数声明中,关键字 auto 表示将使用模板参数推导规则从其 return 语句的操作数推导返回类型。
4) 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.
4) 如果变量的声明类型为decltype(auto),则关键字auto 被其初始化器的表达式(或表达式列表)替换,并使用decltype 的规则推导出实际类型。
5) 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.
5) 如果函数的返回类型声明为decltype(auto),则关键字auto 被替换为其return 语句的操作数,并使用decltype 的规则推导出实际的返回类型。
6) 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.
6) 形式为 auto:: 的嵌套名称说明符是一个占位符,它按照约束类型占位符推导的规则被类或枚举类型替换。
7) A parameter declaration in a lambda expression. (since C++14) A function parameter declaration. (concepts TS)
7) lambda 表达式中的参数声明。(C++14 起)函数参数声明。(概念 TS)
NotesUntil 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.
注释在 C++11 之前,auto 具有存储持续时间说明符的语义。auto f() -> int, i = 0;
不允许在一个声明中混合自动变量和函数,如 in 。
For more info : http://en.cppreference.com/w/cpp/language/auto
回答by Jason
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++11 实现中的一个新的标准 C++ 特性。话虽如此,虽然它是简化对象声明以及清理某些调用范式(即基于范围的 for 循环)的语法的绝佳工具,但不要过度使用/滥用它:-)
回答by rahul goyal
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.
auto 关键字指定正在声明的变量的类型将自动从其初始值设定项中扣除。对于函数,如果它们的返回类型是 auto,那么它将在运行时由返回类型表达式求值。
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 .
当我们必须使用迭代器时,它会非常有用。例如对于下面的代码,我们可以简单地使用“自动”而不是编写整个迭代器语法。
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;
}
This is how we can use "auto" keyword
这就是我们如何使用“auto”关键字