имеет ли `const auto` какое-либо значение?


83

Думаю, вопрос достаточно ясен. Будет ли autoключевое слово автоматически определять константу или всегда возвращать неконстантный тип, даже если есть, например. две версии функции (одна возвращает, constа другая - нет).

Для протокола: я использую const auto end = some_container.end()перед циклами for, но не знаю, необходимо ли это или даже отличается от обычного auto.

Ответы:


32

Может быть , вы путаете const_iteratorи const iterator. Первый выполняет итерацию по элементам const, второй не может выполнять итерацию вообще, потому что вы не можете использовать operators++ и - на нем.

Обратите внимание, что вы очень редко выполняете итерацию из container.end(). Обычно вы будете использовать:

const auto end = container.end();
for (auto i = container.begin(); i != end; ++i) { ... }

12
cbeginи cendвернуть const_iteratorпо значению. const autoпо-прежнему имеет свое предназначение и не является избыточным.
далле

2
Так const autoчто полезно в этом общем случае?
rubenvb

@dalle: Я удалил свой абзац до того, как вы смогли прокомментировать, осознав, что я сказал бессмысленные вещи :)
Бенуа

2
Кто-то писал слишком много sql. :)
Andres Jaan Tack

3
auto изменяется на const как на &, его можно использовать в foreach, например: en.cppreference.com/w/cpp/language/auto
Janosimas

97
const auto x = expr;

отличается от

auto x = expr;

в виде

const X x = expr;

отличается от

X x = expr;

Так что используйте const autoи const auto&много, как если бы у вас не было auto.

На разрешение перегрузки не влияет тип возвращаемого значения: constили отсутствие constв lvalue xне влияет на то, какие функции вызываются expr.


17
Нет. Если вы не собираетесь (или не предполагаете) изменять переменную, ее следует объявить const.
Пол Дж. Лукас,

7

Предположим, у вас есть два шаблона:

template<class U> void f1( U& u );       // 1
template<class U> void f2( const U& u ); // 2

autoвыведет тип и переменная будет иметь тот же тип, что и параметр u(как в // 1случае), const autoсделает переменную того же типа, что и параметр uв // 2случае. Так const autoчто просто форсируйте constквалификатор.


3

Компилятор определяет тип автоматического квалификатора. Если выведенная тип some_type, const autoбудет преобразован const some_type. Однако хороший компилятор изучит всю область autoпеременной и найдет, изменилось ли ее значение где-нибудь. Если нет, то компилятор сам выведет такой тип: auto-> const some_type. Я пробовал это в Visual Studio Express 2012, и производимый машинный код одинаков в обоих случаях, я не уверен, что каждый компилятор будет делать это. Но это хорошая практика по const autoтрем причинам:

  • Предотвращение ошибок кодирования. Вы намеревались, чтобы эта переменная не изменялась, но каким-то образом где-то в области ее действия она изменилась.
  • Читаемость кода улучшена.
  • Вы помогаете компилятору, если он по какой-то причине не выводит constдля auto.

Компилятор не будет выводить константу, если это возможно ... Он добавит константу только в том случае, если выражение, которое он выводит, уже само по себе является константой. Если компилятор просто добавит константу для того, чтобы это было возможно, семантика программы может быть нарушена, например, вызовы функций-членов константные и неконстантные в зависимости от того, может ли конкретный компилятор вывести константу или нет. Так что я думаю, что ваш последний пункт неверен.
rubenvb

@rubenvb Стандарты C ++ позволяют компиляторам реорганизовывать код любым удобным для них способом в зависимости от желаемых оптимизаций. Это совершенно законно компилятор выводить constдля , auto если он не изменяет функциональные возможности программы в любом случае . Это также включает проверки, доступны ли функции-члены const и неконстантные. Компилятор все сделает правильно.
BJovke
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.