czy „const auto” ma jakieś znaczenie?

82

Myślę, że pytanie jest wystarczająco jasne. Czy autosłowo kluczowe automatycznie wykryje stałą, czy zawsze zwróci typ inny niż stała, nawet jeśli istnieją np. dwie wersje funkcji (jedna, która zwraca, consta druga nie).

Tak dla przypomnienia, używam const auto end = some_container.end()przed moimi pętlami for, ale nie wiem, czy jest to konieczne, czy nawet różni się od normalnego auto.

rubenvb
źródło

Odpowiedzi:

31

Może jesteś mylący const_iteratori const iterator. Pierwsza z nich iteruje po elementach const, druga nie może w ogóle iterować, ponieważ nie możesz użyć na nim operators++ i -.

Zauważ, że bardzo rzadko wykonujesz iterację z container.end(). Zwykle będziesz używać:

const auto end = container.end();
for (auto i = container.begin(); i != end; ++i) { ... }
Benoit
źródło
12
cbegini cendzwraca const_iteratorwartość. const autonadal ma swój cel i nie jest zbędny.
dalle
2
Więc const autojest przydatne w tym ogólnym przypadku?
rubenvb,
@dalle: Usunąłem swój akapit, zanim mogłeś skomentować, zdając sobie sprawę, że powiedziałem tylko bezsensowne rzeczy :)
Benoit,
2
Ktoś pisze za dużo sql. :)
Andres Jaan Tack
3
auto jest modyfikowane przez const, jak przez &, może być używane w foreach, na przykład: en.cppreference.com/w/cpp/language/auto
Janosimas
97
const auto x = expr;

różni się od

auto x = expr;

tak jak

const X x = expr;

różni się od

X x = expr;

Więc używaj const autoi const auto&dużo, tak jak gdybyś nie miał auto.

Zwracany typ nie ma wpływu na rozpoznanie przeciążenia: wartość constlub nie constw lvalue xnie wpływa na wywoływane funkcje expr.

antonakos
źródło
17
Nie. Jeśli nie zamierzasz (lub nie powinieneś) modyfikować zmiennej, należy ją zadeklarować const.
Paul J. Lucas
7

Rozważ, że masz dwa szablony:

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

autowydedukuje typ, a zmienna będzie miała ten sam typ co parametr u(jak w tym // 1przypadku), const autosprawi, że zmienna będzie tego samego typu, co parametr uw // 2przypadku. Więc const autopo prostu wymuś constkwalifikator.

Kirill V. Lyadvinsky
źródło
3

Kompilator określa typ kwalifikatora automatycznego. Jeśli typ wywnioskowany to some_type, const autozostanie przekonwertowany na const some_type. Jednak dobry kompilator zbada cały zakres autozmiennej i ustali, czy jej wartość gdziekolwiek się zmieni. Jeśli nie, kompilator sam wydedukuje typ w następujący sposób: auto-> const some_type. Wypróbowałem to w Visual Studio Express 2012 i wyprodukowany kod maszynowy jest taki sam w obu przypadkach, nie jestem pewien, czy każdy kompilator to zrobi. Ale dobrą praktyką jest stosowanie const autoz trzech powodów:

  • Zapobieganie błędom kodowania. Zamierzałeś, aby ta zmienna się nie zmieniała, ale gdzieś w swoim zakresie została zmieniona.
  • Poprawiono czytelność kodu.
  • Pomóc kompilator jeśli z jakiegoś powodu nie wydedukować constna auto.
BJovke
źródło
Kompilator nie wydedukuje const, jeśli jest to możliwe ... Doda const tylko wtedy, gdy wyrażenie, którego typ wywnioskuje, jest już const. Jeśli kompilator po prostu dodałby const, aby było to możliwe, semantyka programu może zostać zepsuta, na przykład wywoływane są funkcje składowe const vs non-const w zależności od tego, czy konkretny kompilator może wydedukować stałą, czy nie. Więc myślę, że twój ostatni punkt jest błędny.
rubenvb
@rubenvb Standardy C ++ pozwalają kompilatorom na reorganizację kodu w dowolny sposób, w zależności od pożądanych optymalizacji. Jest to całkowicie legalne kompilator wywnioskować constna auto razie nie zmienia funkcjonalności programu w żaden sposób . Obejmuje to również sprawdzenie, czy dostępne są funkcje składowe typu const i non-const. Kompilator zrobi to dobrze.
BJovke