Есть ли причина использовать ключевое слово "auto" в C++03?
Примечание этот вопрос был первоначально опубликован в 2009 году, до того, как C++11 был ратифицирован и до значения
auto
ключевое слово было кардинально изменено. Представленные ответы относятся только к значению C++03auto
-- Это указанный класс хранения - а не значение C++11auto
- Это автоматический вывод типа. Если вы ищете советы о том, когда использовать C++11auto
этот вопрос не имеет отношения к этот вопрос.
долгое время я думал, что нет причин использовать static
ключевое слово в C, потому что переменные, объявленные вне области блока, были неявно глобальными. Затем я обнаружил, что объявление переменной как static
в пределах блочной области даст ему постоянную длительность, а объявление его вне блочной области (в области программы) даст ему файловую область (может быть доступна только в этом блоке компиляции).
так что это оставляет меня только с одним ключевое слово, которое я (может быть) еще не полностью понимаю:auto
ключевое слово. Есть какой-то другой смысл, кроме локальной переменной?- Все, что он делает, не подразумевается для вас, где бы вы ни захотели его использовать? Как это auto
переменная ведет себя в области действия программы? А как же static auto
переменная в области действия файла? Имеет ли это ключевое слово какую-либо цель, кроме просто существует для полноты?
10 ответов:
auto
является спецификатором класса хранения,static
,register
иextern
тоже. Вы можете использовать только один из этих четырех в декларации.локальные переменные (без
static
) есть автоматическая длительность хранения, что означает, что они живут с самого начала их определения до конца блока. Установка auto перед ними избыточна, так как это все равно по умолчанию.я не знаю никаких причин, чтобы использовать его в C++. В старых версиях C, которые имеют неявные int правило, вы можете использовать его для объявления переменной
int main(void) { auto i = 1; }
чтобы сделать его допустимым синтаксисом или устранить неоднозначность из выражения присваивания в случае
i
в области. Но это не работает в C++ в любом случае (вы должны указать тип). Довольно забавно, стандарт C++ пишет:объект, объявленный без спецификатора класса хранения в области блока или объявленный как параметр функции, по умолчанию имеет автоматическую продолжительность хранения. [Примечание: следовательно, авто спецификатор почти всегда избыточен и не часто используется; одно использование auto заключается в том, чтобы явно отличать оператор объявления от оператора выражения (6.8). -конец Примечание]
, который относится к следующему сценарию, который может быть как литой
a
в int или объявление переменнойa
типаint
наличие избыточных скобок вокругa
. Это всегда считается декларацией, так чтоauto
не добавил бы здесь ничего полезного, но для человека, вместо. Но опять же, человеку было бы лучше удалить лишние скобки вокругa
, Я бы сказал.int(a);
С новым значением
auto
прибывая с C++0x, я бы не рекомендовал использовать его со значением C++03 в коде.
В C++11,
auto
имеет новое значение: он позволяет автоматически выводить тип переменной.почему это не полезно? Рассмотрим простой пример:
std::list<int> a; // fill in a for (auto it = a.begin(); it != a.end(); ++it) { // Do stuff here }
The
auto
там создается итератор типаstd::list<int>::iterator
.это может сделать некоторые серьезно сложный код гораздо легче читать.
еще пример:
int x, y; auto f = [&]{ x += y; }; f(); f();
там
auto
выведен тип, необходимый для хранения лямбда-выражения в a переменная. Википедия имеет хорошие освещение по этому вопросу.
ключевое слово auto не имеет цели в данный момент. Вы совершенно правы, что он просто пересчитывает класс хранения по умолчанию локальной переменной, действительно полезной альтернативой является
static
.Он имеет совершенно новое значение в C++0х. Что дает вам некоторое представление о том, как бесполезно было!
GCC имеет специальное использование
auto
для вложенных функций-см. здесь.Если у вас есть вложенная функция, которую вы хотите вызвать до ее определения, вам нужно объявить ее с помощью
auto
.
"авто" якобы говорит компилятору решить для себя, куда поместить переменную (память или регистр). Его аналогом является" регистр", который якобы говорит компилятору попытаться сохранить его в регистре. Современные компиляторы игнорируют оба, так что Вы тоже должны.
Я использую это ключевое слово для явного документирования, когда это важно для функции, чтобы переменная была помещена в стек, для стековых процессоров. Эта функция может потребоваться при изменении стека перед возвратом из функции (или процедуры обслуживания прерывания). В этом случае я заявляю:
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
ключевое слово помогает задокументировать намерения.
согласно Строструпу, в "языке программирования C" (4-е издание, охватывающее C 11) использование "auto" имеет следующие основные причины (раздел 2.2.2) (слова Строструпа цитируются):
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; }
в старом компиляторе auto был одним из способов объявить локальную переменную вообще. Вы не можете объявлять локальные переменные в старых компиляторах, таких как Turbo C, без ключевого слова auto или некоторых других.
новое значение ключевого слова auto в C++0x очень хорошо описано Стефаном т. Лававеем из Microsoft в свободно просматриваемой / загружаемой видео-лекции по STL, найденной на сайте канала 9 MSDN здесь.
лекцию стоит просмотреть полностью, но часть о ключевом слове auto находится примерно на отметке 29-й минуты (приблизительно).
есть ли какое-то другое значение для "авто", кроме "локальной переменной"?-
не в C++03.
все, что он делает, что неявно сделано для вас, где бы вы ни хотели его использовать?
ничего вообще, в C++03.
как ведет себя автоматическая переменная в области действия программы? Как насчет статической автоматической переменной в области действия файла?
Ключевое слово не допускается вне функции / метода тело.
имеет ли это ключевое слово какую-либо цель [в C++03], кроме просто существующего для полноты?
удивительно, да. Критерии проектирования C++ включали высокую степень обратной совместимости с C. C имел это ключевое слово, и не было никакой реальной причины запретить его или переопределить его значение в C++. Итак, цель была одна меньше несовместимость с С.
имеет ли это ключевое слово какую-либо цель в C, кроме просто существующего для полнота?
я узнал один только недавно: легкость переноса древних программ из B. C развилась из языка под названием B, синтаксис которого был очень похож на синтаксис C. Однако у B не было типов вообще. Единственный способ объявить переменную в B - указать ее тип хранения (
auto
илиextern
). Вот так:auto i;
этот синтаксис все еще работает в C и эквивалентен
int я;
потому что в C класс хранения по умолчанию
auto
, и тип по умолчаниюint
. Я думаю, что каждая программа, которая возникла в B и была портирована на C, была буквально полнаauto
переменные в то время.C++03 больше не допускает неявного int стиля C, но он сохранил больше не точно полезный
auto
ключевое слово, потому что в отличие от неявного int, он не вызывал никаких проблем в синтаксисе C.