C++自动关键字.为什么它很神奇?

Ann*_*inn 130 c++ types auto c++11

从我以前学习C++的所有材料来看,auto一直是一个奇怪的存储持续时间说明符,它没有任何用途.但就在最近,我遇到的代码将其用作类型名称.出于好奇,我尝试了它,它假设我碰巧分配给它的类型!

突然间,STL迭代器以及使用模板的任何东西都比写入容易10倍.感觉就像我正在使用像Python这样的"有趣"语言.

这个关键词一直在哪里?你会说它是视觉工作室独有的还是不可移植的?

Jer*_*fin 133

auto 是一个C++"继承"的关键词,它几乎永远存在于C中,但实际上从未使用过,因为只有两个可能的条件:要么是不允许的,要么是默认情况下假设的.

auto用于表示推导类型的用法是C++ 11的新增功能.

同时auto x = initializer,xinitializer模型类型推导适用于函数模板的相同方式推导出类型f 的类型.考虑这样的函数模板:

template<class T>
int whatever(T t) { 
    // point A
};
Run Code Online (Sandbox Code Playgroud)

在A点,已T根据为参数传递的值指定了类型whatever.执行此操作时auto x = initializer;,将使用相同类型的推导来确定用于初始化它x的类型initializer.

这意味着编译器需要实现的大多数类型推导机制auto已经存在,并且用于任何甚至尝试实现C++ 98/03的编译器上的模板.因此,auto对于基本上所有编译器团队来说,添加支持显然相当容易 - 它添加得相当快,而且似乎也很少有与之相关的错误.

当这个答案最初编写时(2011年,在C++ 11标准的墨水干燥之前)auto已经非常便携了.如今,它在所有主流编译器中都是完全可移植的.避免它的唯一明显理由是,如果您需要编写与C编译器兼容的代码,或者您需要针对某些您不知道不支持它的利基编译器(例如,少数人仍然编写代码)对于使用Borland,Watcom等编译器的MS-DOS,几十年来没有出现过显着的升级).如果您正在使用任何主流编译器的合理当前版本,那么根本没有理由避免使用它.

  • 从 C++20 开始,还可以使用 [`auto` 作为函数参数类型](/sf/answers/4224887761/)。 (2认同)

Nic*_*las 19

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

  • @Clairvoire C++ 0x是临时名称.它已于本月发布,因而成为C++ 11. (7认同)

R. *_*des 11

这个功能一直没有出现过.自2010版以来,Visual Studio一直支持它.这是一个新的C++ 11功能,因此它不是Visual Studio独有的,并且/将是可移植的.大多数编译器已经支持它.


Pra*_*are 9

对于变量,指定将从其初始化程序自动推导出正在声明的变量的类型.对于函数,指定返回类型是尾随返回类型,或者将从其返回语句推断出(自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)
Run Code Online (Sandbox Code Playgroud)

说明

1)当在块范围,命名空间范围,for循环的初始化语句等中声明变量时,关键字auto可以用作类型说明符.一旦初始化的类型已经确定,编译器确定将取代使用用于从函数调用模板参数推导规则的关键字自动(见模板实参推演#的详细信息其他上下文)的类型.关键字auto可以附带修饰符,例如const或&,它们将参与类型推导.例如,给定const auto& i = expr;,template<class U> void f(const U& u)如果f(expr)编译函数调用,则i的类型正是虚构模板中参数u的类型.因此,auto &&可以根据初始化器推导为左值引用或右值引用,初始化器用于基于范围的for循环.如果auto用于声明多个变量,则推导出的类型必须匹配.例如,声明格式auto i = 0, d = 0.0;不正确,而声明auto i = 0, *p = &i;格式正确,自动推断为int.

2)在使用尾随返回类型语法的函数声明中,关键字auto不执行自动类型检测.它只是语法的一部分.

3)在不使用尾随返回类型语法的函数声明中,关键字auto表示将使用模板参数推导的规则从其return语句的操作数推导出返回类型.

4)如果变量声明的类型是decltype(自动),关键字自动替换其初始化的表达(或表达列表),以及实际的类型是使用用于decltype的规则推导的.

5)如果函数的返回类型声明为decltype(auto),则将关键字auto替换为其return语句的操作数,并使用decltype规则推导实际返回类型.

6)auto ::形式的嵌套名称说明符是一个占位符,它由类或枚举类型替换,遵循约束类型占位符扣除的规则.

7)lambda表达式中的参数声明.(自C++ 14开始)一个函数参数声明.(概念TS)

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

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


小智 6

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; 
}
Run Code Online (Sandbox Code Playgroud)

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


Jas*_*son 5

它不会去任何地方......它是 C++11 实现中的一个新的标准 C++ 功能。话虽这么说,虽然它是简化对象声明以及清理某些调用范式(即基于范围的 for 循环)的语法的绝佳工具,但不要过度使用/滥用它:-)


eas*_*000 5

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

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

第一条规则

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

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.
Run Code Online (Sandbox Code Playgroud)

第二条规则

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

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

int y = 10;
auto& x = y; // The type of variable x is int&.
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

第三条规则

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. 
Run Code Online (Sandbox Code Playgroud)

  • 解释得很好。谢谢。读起来非常丰富。 (2认同)