有没有理由在C ++ 03中使用'auto'关键字?

时间:2009-06-25 22:05:04

标签: c++ keyword c++03

  

注意此问题最初发布于2009年,在批准C ++ 11之前和auto关键字的含义发生重大变化之前。提供的答案只适用于 auto的C ++ 03含义 - 指定的存储类 - 而不是auto的C ++ 11含义 - - 那是自动型扣除。如果您正在寻找有关何时使用C ++ 11 auto的建议,则此问题与该问题无关。

在最长的时间里,我认为没有理由在C中使用static关键字,因为在块范围之外声明的变量是隐式全局的。然后我发现在块范围内将变量声明为static会给它永久持续时间,并且在块范围之外(在程序范围内)声明它会给它文件范围(只能在其中访问)编制单位)。

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

10 个答案:

答案 0 :(得分:86)

在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表达式存储在变量中所需的类型。 维基百科有很好的coverage on the subject.

答案 1 :(得分:74)

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

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

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

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

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

  

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

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

int(a);

随着auto的新含义到达C ++ 0x,我不鼓励在代码中使用C ++ 03的含义。

答案 2 :(得分:34)

目前auto关键字没有用处。你完全正确的是它只重述了局部变量的默认存储类,真正有用的替代方法是static

它在C ++ 0x中有brand new meaning。这让你知道它是多么无用!

答案 3 :(得分:7)

GCC特别使用auto来嵌套函数 - 请参阅here

如果您在定义之前要调用嵌套函数,则需要使用auto声明它。

答案 4 :(得分:3)

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

答案 5 :(得分: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关键字有助于记录意图。

答案 6 :(得分:2)

根据Stroustrup的说法,在“C程序设计语言”(第4版,涵盖C 11)中,使用'auto'有以下主要原因(第2.2.2节)(引用了Stroustrup词):

1)

  

定义是在我们想要制作类型的大范围内   读者清楚地看到我们的代码。

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

2)

  

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

在我看来,适合这里的案例是这样的:

   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;
}

答案 7 :(得分:1)

在旧编译器中,auto是一种声明局部变量的方法。你不能在没有auto关键字的Turbo C等旧编译器中声明局部变量。

答案 8 :(得分:1)

微软的Stephan T. Lavavej在MSDN的第9频道网站here上发表了关于STL的免费可视/可下载视频讲座,非常清楚地描述了C ++ 0x中auto关键字的新含义。

讲座值得全面查看,但关于auto关键字的部分大约是第29分钟(大约)。

答案 9 :(得分:0)

“自动”还有其他一些含义吗?除了&#39;局部变量?&#39;

不在C ++ 03中。

无论你想在哪里使用它,它都不会隐含地为你做什么?

无论如何,在C ++ 03中。

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

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

这个关键字是否具有[在C ++ 03中]的目的,而不仅仅是为了完整性而存在?

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

此关键字在C中是否具有任何目的,而不仅仅是为了完整性而存在?

我最近才学会了一个:从B语言中移植古代程序的容易程度。从一种名为B的语言演变而来,其语法与C语言非常相似。但是,B没有任何类型。在B中声明变量的唯一方法是指定其存储类型(autoextern)。像这样:

  

auto i;

此语法仍然适用于C,相当于

  

int i;

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

C ++ 03不再允许C样式隐式int,但它保留了不再完全有用的auto关键字,因为与隐式int不同,它不会导致任何麻烦在C的语法中。