85

注意这个问题最初是在 2009 年发布的,在 C++11 被批准之前并且在auto关键字的含义发生巨大变化之前。提供的答案与 C++03 的含义有关auto——即指定的存储类——而不是 C++11 的含义auto——即自动类型推导。如果您正在寻找有关何时使用 C++11 的建议auto,则此问题与该问题无关。

很长一段时间以来,我认为没有理由static在 C 中使用关键字,因为在块范围之外声明的变量是隐式全局的。然后我发现将变量声明为static在块范围内会赋予它永久的持续时间,而在块范围之外(在程序范围内)声明它会给它文件范围(只能在该编译单元中访问)。

所以这给我留下了一个我(也许)还没有完全理解的关键字:auto关键字。除了“局部变量”之外,它还有其他含义吗?无论您想在哪里使用它,它所做的任何事情都没有为您隐含地完成?auto变量在程序范围内的行为如何?文件范围内的static auto变量是什么?除了为了完整性而存在之外,此关键字是否还有其他用途?

4

10 回答 10

85

在 C++11 中,auto有了新的含义:它允许您自动推断变量的类型。

为什么这总是有用的?让我们考虑一个基本的例子:

std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
  // Do stuff here
}

auto那里创建了一个类型为 的迭代器std::list<int>::iterator

这可以使一些非常复杂的代码更容易阅读。

另一个例子:

int x, y;
auto f = [&]{ x += y; };
f();
f();

在那里,auto推导出将 lambda 表达式存储在变量中所需的类型。维基百科对这个主题有很好的报道。

于 2012-06-14T21:49:58.153 回答
75

auto是一个存储类说明符,staticregister也是extern。您只能在声明中使用这四种中的一种。

局部变量(没有static)具有自动存储持续时间,这意味着它们从定义开始到块结束都存在。将 auto 放在它们前面是多余的,因为无论如何这是默认设置。

我不知道有什么理由在 C++ 中使用它。在具有隐式 int 规则的旧 C 版本中,您可以使用它来声明变量,例如:

int main(void) { auto i = 1; }

使其语法有效或与赋值表达式消除歧义,以防万一i在范围内。但这无论如何在 C++ 中都不起作用(你必须指定一个类型)。有趣的是,C++ 标准写道:

在块范围内声明没有存储类说明符或声明为函数参数的对象默认具有自动存储持续时间。[注意:因此, auto 说明符几乎总是多余的并且不经常使用;auto 的一种用途是明确区分声明语句和表达式语句(6.8)。——尾注]

它指的是以下场景,它可以是 to 的强制转换,也可以是a在.周围有多余括号的类型int变量的声明。它总是被认为是一个声明,所以不会在这里添加任何有用的东西,而是为人类添加。但是话又说回来,人类最好删除 周围的多余括号,我会说:aintaautoa

int(a);

auto有了C++0x的新含义,我不鼓励在代码中使用 C++03 的含义。

于 2009-06-25T22:13:50.223 回答
35

auto 关键字目前没有任何用途。你说得对,它只是重述了局部变量的默认存储类,真正有用的替代方案是static.

它在 C++0x 中具有全新的含义。这让你知道它是多么无用!

于 2009-06-25T22:06:45.263 回答
7

autoGCC对嵌套函数有特殊用途- 请参见此处

如果您想在定义之前调用嵌套函数,则需要使用auto.

于 2009-06-26T07:34:29.420 回答
3

“auto”应该告诉编译器自己决定将变量(内存或寄存器)放在哪里。它的模拟是“寄存器”,据说它告诉编译器尝试将它保存在寄存器中。现代编译器忽略了两者,所以你也应该这样做。

于 2009-06-25T23:07:40.787 回答
3

对于基于堆栈的处理器,我使用此关键字来明确记录何时对函数至关重要,将变量放置在堆栈上。在从函数(或中断服务程序)返回之前修改堆栈时,可能需要此函数。在这种情况下,我声明:

auto unsigned int auiStack[1];   //variable must be on stack

然后我访问变量外部:

#define OFFSET_TO_RETURN_ADDRESS 8     //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;

因此,auto关键字有助于记录意图。

于 2012-06-14T21:31:56.497 回答
2

根据 Stroustrup 的说法,在“The C Programming Language”(第 4 版,涵盖 C 11)中,使用“auto”有以下主要原因(第 2.2.2 节)(引用 Stroustrup 的话):

1)

该定义的范围很大,我们希望使代码的读者可以清楚地看到该类型。

使用 'auto' 及其必要的初始化程序,我们可以一眼就知道变量的类型!

2)

我们希望明确变量的范围或精度(例如,双精度而不是浮点)

在我看来,适合这里的情况是这样的:

   double square(double d)
    {
        return d*d; 
    }

    int square(int d)
    {
        return d*d; 
    }

    auto a1 = square(3);

    cout << a1 << endl;

    a1 = square(3.3);

    cout << a1 << endl;

3)

使用 'auto' 我们避免了冗余和编写长类型名称。

想象一下来自模板化迭代器的一些长类型名称:

(来自第 6.3.6.1 节的代码)

template<class T> void f1(vector<T>& arg) {
    for (typename vector<T>::iterator p = arg.begin(); p != arg.end();   p)
        *p = 7;

    for (auto p = arg.begin(); p != arg.end();   p)
        *p = 7;
}
于 2013-06-06T00:23:50.123 回答
1

在旧的编译器中, auto 是一种声明局部变量的方法。在没有 auto 关键字或类似关键字的情况下,您无法在 Turbo C 等旧编译器中声明局部变量。

于 2010-06-07T20:31:01.347 回答
1

C++0x 中 auto 关键字的新含义由 Microsoft 的 Stephan T. Lavavej 在 MSDN 的第 9 频道站点上的可免费查看/可下载的 STL 视频讲座中很好地描述

讲座值得完整观看,但关于 auto 关键字的部分大约在第 29 分钟(大约)。

于 2010-11-19T18:22:14.760 回答
1

除了“局部变量”之外,“自动”还有其他含义吗?

不在 C++03 中。

无论您想在哪里使用它,它所做的任何事情都没有为您隐含地完成?

什么都没有,在 C++03 中。

自动变量在程序范围内的行为如何?文件范围内的静态自动变量是什么?

在函数/方法体之外不允许使用关键字。

除了为了完整性而存在之外,此关键字是否有任何用途 [在 C++03 中]?

令人惊讶的是,是的。C++ 设计标准包括与 C 的高度向后兼容性。C 有这个关键字,没有真正的理由禁止它或重新定义它在 C++ 中的含义。因此,目的是减少与 C 的不兼容。

除了为了完整性而存在之外,这个关键字在 C 中是否还有其他用途?

我最近才知道一个:从 B 中移植古代程序的便利性。C 是从一种叫做 B 的语言演变而来的,它的语法与 C 的语法非常相似。但是,B 没有任何类型。在 B 中声明变量的唯一方法是指定其存储类型(autoextern)。像这样:

自动我;

此语法在 C 中仍然有效,等效于

诠释我;

因为在 C 中,存储类默认为auto,类型默认为int。我猜想每个源自 B 并被移植到 C 的程序在当时实际上都充满了auto变量。

C++03 不再允许 C 风格的隐式 int,但它保留了不再完全有用的auto关键字,因为与隐式 int 不同,它不会在 C 的语法中造成任何问题。

于 2015-09-30T16:45:37.473 回答