Путаница с ключевым словом auto в С++

Меня смущает следующий фрагмент кода:

#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 – тип данных, тогда почему в первом случае я получаю сообщение об ошибке "два или более типов данных"?


person msc    schedule 12.04.2017    source источник
comment
Вы путешественник во времени из прошлого?   -  person Constructor    schedule 12.04.2017
comment
Я не груб, но я никогда не видел, чтобы кто-то использовал auto в качестве спецификатора класса хранения в дикой природе. Я думаю, именно поэтому люди согласились, что это может быть переназначено. В любом случае теперь (C++11 on) это означает automatically выводить тип, и это потрясающе.   -  person Persixty    schedule 12.04.2017
comment
Да, они согласились изменить его, потому что так и не нашли доказательств его использования за пределами наборов тестов соответствия компилятора.   -  person Puppy    schedule 12.04.2017
comment
люди, которые голосуют за то, что это не по теме, ошибаются. это законный вопрос, но дубликат   -  person Ryan Haining    schedule 12.04.2017
comment
Я виню в этом старые учебники, которые все еще распространяются.   -  person Trevor Hickey    schedule 13.04.2017


Ответы (4)


auto не является классом хранения. Раньше это было до C++11. Но это было совершенно бесполезно, поэтому ключевое слово было переназначено для автоматического определения типа. Итак, когда вы говорите:

auto int ret = foo();

Вы в основном объявляете, что объект имеет 2 типа (или, возможно, один и тот же тип дважды), и это ошибка. И когда вы говорите:

auto ret = foo();

Тип ret определяется тем, что возвращает функция foo, в данном случае это int*.

person Benjamin Lindley    schedule 12.04.2017
comment
Обратите внимание, что auto по-прежнему является классом хранения в C, даже в последней версии стандарта. Там он так же бесполезен, как и в C++, но комитет C имеет тенденцию быть гораздо более консервативным в отношении возни с зарезервированными словами. - person zwol; 12.04.2017


auto НЕ является классом хранения (уже не с C++11). C++11 содержит ключевое слово, позволяющее компилятору сделать вывод о том, какой тип требуется для объявляемой переменной.

поэтому в основном выполнение auto int myVar так же недопустимо, как string double myVar2 или bool long myVar3... переменная может иметь только один тип данных, определяющий это, и в вашем случае это делает ключевое слово auto...

как избавиться от ошибки:

Удалите тип int и просто используйте auto, это позволит компилятору *AUTO*** автоматически определить этот тип переменной **ret именно то, что возвращает foo() :) просто гениально!

auto ret = foo();

из документа:

Для переменных указывает, что тип объявляемой переменной будет автоматически выведен из ее инициализатора. Для функций указывает, что тип возвращаемого значения является конечным возвращаемым типом или будет выведен из его операторов возврата (начиная с C++14). для параметров шаблона, не являющихся типом, указывает, что тип будет выведен из аргумента

person ΦXocę 웃 Пepeúpa ツ    schedule 12.04.2017

Вы написали, что:

auto — это класс хранения

но это уже не так в C++11 (или более поздней версии). Ключевое слово auto было повторно использовано для чего-то совершенно другого (некоторого ограниченного вида вывод типа). Бывший класс хранения C++03 или C99 auto теперь (в C++11) всегда является неявным и не должен не использовать ключевое слово auto.

(если вам нравится вывод типов, C++11 делает это не очень хорошо, но C++14 или C++17 продвинулись в этом; у Ocaml гораздо более мощный и интересный вывод типа Хиндли-Милнера, который является более "глобальным"; поэтому я написал "какой-то ограниченный тип ")

person Basile Starynkevitch    schedule 12.04.2017
comment
Зачем давать ответ, если вы не уверены, что auto делает в современном C++? - person Jesper Juhl; 12.04.2017
comment
С чего ты взял, что я не уверен? На самом деле, я почти уверен в том, что написал. И auto выполняет некоторый очень ограниченный вывод типа (гораздо менее мощный, чем у Ocaml, например). Отсюда и прилагательное some - person Basile Starynkevitch; 12.04.2017
comment
Почему минус? - person Basile Starynkevitch; 12.04.2017
comment
Не голосующий против, но мне любопытно - что, в двух словах, отсутствует в auto, что делает OCaml? - person Quentin; 12.04.2017
comment
Вывод типа Ocaml (фактически HM) вычисляет домен и цель функций в глобальном масштабе, а не только в одном выражении. - person Basile Starynkevitch; 12.04.2017
comment
@BasileStarynkevitch Я думаю, что c++14 (но не c++11) также имеет вывод типов для функций (и лямбда-выражений), см. en.cppreference.com/w/cpp/language/auto - person Alex Vong; 12.04.2017
comment
Это читается так, как будто C++ тупой, верно? разглагольствовать Сравнение с Ocaml бесполезно для понимания того, что делает C++ auto, или для ответа на вопрос. - person nwp; 12.04.2017
comment
@nwp Сравнение Ocaml было отредактировано для уточнения после того, как кто-то пожаловался на выражение некоторого ограниченного типа вывода типа и спутал его с незнанием. - person mastov; 12.04.2017
comment
Вы сказали, что продолжительность автоматического хранения теперь (в С++ 11) всегда неявна. Но это всегда было неявным, вплоть до C++98 и C89, так что это не изменилось. - person Oktalist; 13.04.2017