Каковы плюсы / минусы использования auto
ключевого слова, особенно в циклах for?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
Похоже, если вы не знаете, есть ли у вас итератор для карты или вектора, вы не знаете, использовать first
ли second
или просто напрямую обращаться к свойствам объекта, нет?
Это напоминает мне спор о том, стоит ли использовать ключевое слово в C # var
. У меня сложилось впечатление, что в мире C ++ люди готовы принять auto
ключевое слово с меньшими усилиями, чем var
в мире C #. Для меня мой первый инстинкт заключается в том, что мне нравится знать тип переменной, чтобы я мог знать, какие операции я могу ожидать над ней.
var
? Я пропустил это.for (auto& it : x)
(или без ссылки, если вы хотите копировать)x
и вы даже не знаете, что этоx
такое, вы не должны писать этот цикл в первую очередь ;-)Ответы:
Мотивации в C ++ более экстремальны, поскольку типы могут стать значительно более запутанными и сложными, чем типы C #, из-за метапрограммирования и других вещей.
auto
быстрее писать и читать и более гибкий / обслуживаемый, чем явный тип. Я имею в виду, ты хочешь начать печататьЭто даже не полный тип. Я пропустил пару аргументов шаблона.
источник
auto
. По дизайну.typedef
помогает, ноauto
помогает больше.В вашем примере:
должна быть декларация для
x
видимого. Поэтому типit
должен быть очевидным. Если типx
неочевиден, то метод слишком длинный или класс слишком большой.источник
x
это очень плохое имя переменной для контейнера. В некоторых ситуациях вы, скорее всего, можете просто посмотреть на (семантически ценное) имя и сделать вывод о возможных операциях.x
в качестве общего примера, я склонен использовать достаточно описательные имена переменных.Возражение ! Загруженный вопрос.
Можете ли вы объяснить мне, почему третий код содержит
??
, а первый и второй нет? Справедливости ради, ваш код должен выглядеть следующим образом:Там. Та же проблема, даже если вы не использовали
auto
.И во всех случаях ответ один и тот же: контекст имеет значение . Вы не можете осмысленно говорить о куске кода изолированно. Даже если бы вы не использовали шаблоны, а использовали какой-то конкретный тип, это только переместило бы проблему куда-нибудь еще, поскольку читатель вашего кода должен был бы знать об объявлении указанного типа.
Если использование
auto
в таких ситуациях делает ваш код нечитаемым, вы должны воспринимать это как предупреждение о том, что с вашим дизайном кода что-то не так. Конечно, есть случаи, когда низкоуровневые детали имеют значение (например, при работе с битовыми операциями или устаревшим API), когда явный тип может способствовать удобочитаемости. Но в целом - нет.Что касается
var
(поскольку вы прямо упомянули об этом), в сообществе C # также существует широкий консенсус в отношении использованияvar
. Аргументы против его использования обычно основаны на заблуждениях .источник
T
это настолько же непрозрачно для пользователя, как иauto
. И все же один должен быть в порядке, а другой нет ?! Это не имеет смысла. В случае OP,T
является заменой для произвольного типа. В реальном коде это может быть использование шаблонов(for typename std::vector<T>::iterator…)
или интерфейс класса. В обоих случаях фактический тип скрыт от пользователя, и все же мы обычно пишем такой код без проблем.auto
. Понятно, какие операцииx
поддерживает из контекста. Фактически, тип не дает вам никакой дополнительной информации: в любом случае вам понадобится какой-то дополнительный (IDE, документация, знания / память), чтобы сообщить вам набор поддерживаемых операций.begin
возвращается , но вы же знаете , чтоstd::vector<>::iterator
есть. И вам нужно использовать плохой инструмент программирования, который не может дать вам эту информацию тривиально. Это очень запутанный. В действительности вы либо знаете и то,begin
иiterator
другое, или нет, и вам следует использовать IDE или редактор, который может легко предоставить вам соответствующую информацию. Это может сделать каждый современный IDE и редактор программ.PRO
Ваш код :
не собирается компилироваться из-за зависимого от шаблона имени.
Это правильный синтаксис:
Посмотрите, как долго объявление типа. Это говорит о том, почему
auto
было введено ключевое слово. Эта :является более кратким. Итак, это профессионал.
ПРОТИВ
Вы должны быть немного осторожны. С ключевым словом
auto
вы получите тип, который вы объявили.Например :
против
В заключение: да, вы должны это, но не злоупотреблять этим. Некоторые люди склонны использовать его слишком часто, и везде ставят auto, как в следующем примере:
против
источник
auto i = 0
, Guilty. Я делаю это. Но это потому, что я знаю, что0
это буквальный типint
. (и восьмеричная константа ;-))Да, ты должен!
auto
не стирает тип; даже если вы «не знаете», чтоx.begin()
такое, компилятор знает и сообщит об ошибке, если вы попытаетесь использовать тип неправильно. Кроме того, нет ничего необычного в том, чтобы эмулироватьmap
с помощью avector<pair<Key,Value>>
, поэтому использование кодаauto
будет работать для обоих представлений в словаре.источник
Да, вы должны использовать
auto
в качестве правила по умолчанию. Он имеет ряд преимуществ по сравнению с явным указанием типа:Здесь у вас есть выбор. Есть также случаи, когда у вас нет выбора:
При условии, что вы точно знаете, что делаете
auto
, у него нет недостатков.источник