C++中auto关键字的困惑

24

我对以下代码感到困惑:

#include <iostream>
using namespace std;

int *foo()
{
   //Operation
}

int main ()
{
        auto int ret = foo();
}

我在GCC下编译了上述代码,但是出现了以下错误:

error: two or more data types in declaration of 'ret'
         auto int ret = foo();

但是,如果我删除int类型,就像这样:

auto ret = foo();

然后它成功运行。

auto是一个存储类int是一个数据类型,那么在第一种情况下为什么会出现“两个或多个数据类型”错误


85
你是来自过去的时间旅行者吗? - Constructor
18
我并不粗鲁,但我从未见过任何人在实际中使用“auto”作为存储类说明符。我认为这就是为什么人们同意它可以被重新用途的原因。无论如何,现在(C++11起),它意味着自动推断类型,非常棒。 - Persixty
8
是的,他们同意进行更改,因为他们从未找到除编译器符合性测试套件之外的单个用途的证据。 - Puppy
5
把这个当作离题的人是错的,这是一个合法的问题,但已经有类似的提问了(即重复问题)。 - Ryan Haining
我指责那些仍在流传的旧教科书。 - Trevor Hickey
4个回答

43

auto不是一个存储类。在C++11之前,它曾经是。但它完全没用,所以这个关键字被重新用于允许自动类型推导。所以当你说:

auto int ret = foo();

你基本上是在声明对象具有两种类型(或可能是同一类型两次),这是一个错误。当你说:

auto ret = foo();

ret的类型是由函数foo返回的类型决定的,在这种情况下,它是int*


2
请注意,即使在最新的 C 标准中,auto 仍然是一个存储类。它在 C++ 中一样无用,在保留字方面,C 委员会往往更加保守。 - zwol

33

auto是一个存储类。

在C++11之前,这是正确的。但现在不再是这样了。

从C++11开始,这个词的含义已经改变了。它现在用于自动推断类型。详见http://www.stroustrup.com/C++11FAQ.html#auto

为什么在第一种情况下我会得到“两个或更多数据类型”的错误?

使用

auto int ret = foo();

您试图为ret指定两种类型--一种是推导的,另一种是明确指定的。

如果要使用明确指定的类型,可以使用:

int ret = *foo(); // Since foo() returns a pointer.
或者
int* ret = foo();

或者你可以通过使用以下方式让编译器推断类型:

auto ret = foo();  

10

auto不是一个存储类(自C++11以来不再是),C++11引入了这个关键字,允许编译器推断您声明的变量所需的类型。

因此,基本上执行 auto int myVar string double myVar2 bool long myVar3 一样无效......变量只能有一个数据类型定义它,在您的情况下,关键字auto会做到这一点......

如何摆脱错误:

移除 int 类型,只使用 auto ,这样做将让编译器*自动地推断**ret变量的类型正是从foo()返回的类型:) 真是太聪明了!

auto ret = foo();

来自文档

对于变量,指定正在声明的变量的类型将根据其初始化程序自动推导。对于函数,指定返回类型为后置返回类型或将根据其返回语句进行推导(自C++14以来)。对于非类型模板参数,指定该类型将从参数中推导出。


4

你写道:

auto是一种存储类

但这在C++11(或更高版本)中已经不再正确。 auto关键字已被用于完全不同的东西(某种有限的类型推断)。以前的C++03或C99 auto存储类现在(在C++11中)总是隐式的,不应使用auto关键字。

(如果您喜欢类型推断,C++11并没有做得很好,但C++14或C++17在此方面有所进展;Ocaml具有更强大和有趣的Hindley-Milner类型推断,它更“全局”;这就是为什么我写“某种有限的”)


4
不是那个点踩的人,但我很好奇——简单来说,OCaml相比auto有什么优势? - Quentin
1
Ocaml(实际上是HM)类型推断在全局计算函数的定义域和目标,而不仅仅是单个表达式。 - Basile Starynkevitch
2
@BasileStarynkevitch 我认为C++14(但不是C++11)也具有函数类型推断(以及lambda表达式),请参见http://en.cppreference.com/w/cpp/language/auto - Alex Vong
11
这篇文章读起来像是在抱怨“C++很蠢,我说的对吧?”。与Ocaml的比较并没有提供理解C++ auto的价值或回答问题。 - nwp
6
有人抱怨表达“某些受限的类型推断”的说法,误认为是无知,因此编辑了一下Ocaml比较的内容以进行澄清。请注意,这并不改变原文的意思。 - mastov
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接