modern loop instead for based c++ const auto

loop - iterate map c++ 11



Diferencia entre const auto y auto y si el objeto de referencia es const. (5)

Hay una ligera diferencia en el primer caso, el auto se deducirá a const int y en el segundo caso a int (como explico explícitamente el const).

estados de referencia cpp

La palabra clave auto puede ir acompañada de modificadores, como const o &, que participarán en la deducción de tipo. Por ejemplo, dado const auto & i = expr ;, el tipo de i es exactamente el tipo del argumento u en una plantilla imaginaria void f (const U & u) si se compiló la función call f (expr). Por lo tanto, auto && se puede deducir como una referencia de valor l o una referencia de valor de rvalor según el inicializador, que se usa en el rango para el bucle.

Así que para ti esto significa

// case 1 const int i = 42; const auto &k = i; // auto -> int // case 2 const int i = 42; auto &k = i; // auto -> const int

Sin embargo, en mi opinión, lo más importante es que la intención se manifiesta más claramente si se declara la constancia de manera explícita y garantiza la constancia. Por eso en este caso lo preferiría claramente.

// case 1 const int i = 42; const auto &k = i; // case 2 const int i = 42; auto &k = i;

¿Necesitamos la palabra clave const antes de auto en este escenario? Después de todo, una referencia ( k ) a un tipo de deducción automática incluirá la const de nivel superior del objeto ( const int i ). Entonces, creo que k será una referencia a un entero que es constante ( const int &k ) en ambos casos.

Si eso es cierto, ¿significa que const auto &k = i; en caso de que 1 sea reemplazado por el compilador como solo const int &k = i; ( auto siendo reemplazado con int )? Considerando que en el caso 2, auto se sustituye por const int ?


Hola y bienvenidos a la pila de desbordamiento.

Como muestra este pequeño programa de prueba, no importa cómo especifique el tipo de k , el compilador nunca le permitirá perder la constancia de i .

#include <iostream> #include <type_traits> #include <string> #define XSTR(s) STR(s) #define STR(s) #s template<class T> struct type; template<> struct type<int> { static std::string name() { return "int"; } }; template<class T> struct type<T&&> { static std::string name() { return type<T>::name() + " &&"; } }; template<class T> struct type<T&> { static std::string name() { return type<T>::name() + " &"; } }; template<class T> struct type<T const> { static std::string name() { return type<T>::name() + " const"; } }; #define REPORT_CONST(decl, var, assign) / { / decl var = assign; / do_it(STR(decl var = assign;), var); / } template<class Var> void do_it(const char* message, Var&&) { std::cout << "case: " << message << " results in type: " << type<Var>::name() << ''/n''; } int main() { const int i = 42; REPORT_CONST(const auto &, k, i); REPORT_CONST(auto &, k, i); REPORT_CONST(auto &&, k, std::move(i)); REPORT_CONST(auto const &&, k, std::move(i)); REPORT_CONST(int const&, k, i); // REPORT_CONST(int &, k, i); // error: binding reference of type ''int&'' to ''const int'' discards qualifiers }

Resultados previstos:

case: const auto & k = i; results in type: int const & case: auto & k = i; results in type: int const & case: auto && k = std::move(i); results in type: int const & case: auto const && k = std::move(i); results in type: int const & case: int const& k = i; results in type: int const &

http://coliru.stacked-crooked.com/a/7c72c8ebcf42c351

Tenga en cuenta también el decaimiento de los valores r con nombre a valores l.


La deducción de tipo con trabajos auto como la deducción de tipo de argumento de la plantilla con algunas excepciones que no se aplican en el ejemplo dado. Por lo tanto

const int i = 42; const auto& k1 = i; // same as const int& k1 = i; auto& k2 = i; // same as (const int)& k2 = i;

Sin embargo, probablemente sea más legible agregar el calificador const .

Aquí hay otro ejemplo donde favorecer la brevedad con el auto es engañoso:

int *i; const auto k1 = i; // same as int* const k1 = i; const auto *k2 = i; // same as const int *k2 = i;

En el primer caso, el objeto al que i apunto se puede modificar a través de k1 , en el segundo caso, no se puede modificar.


La respuesta aceptada es correcta, es decir, no hay diferencia con respecto al resultado compilado. Lo que es importante tener en cuenta es que el auto& versión están acoplando la constancia de la referencia k con la constancia de la variable i . Pensé que, dado que la pregunta se titula '' Diferencia entre const auto & and auto & ... '', entonces es importante enfatizar la diferencia pragmática aquí, en la que si no coloca la palabra clave const , no puede garantizar que la referencia tendrá Esta cv-calificación . En algunos casos en los que se desea esto , ¿por qué dejarlo al azar para que permanezca const en el futuro?


auto palabra clave auto decide automáticamente el tipo de variable en el momento de la compilación.

En su primer caso, auto se reduce a int donde se reduce a const int en el segundo caso. Por lo tanto, ambos casos se reducen al mismo código que:

const int &k = i;

Sin embargo, es mejor tener la constante explícitamente para una mejor legibilidad y asegurarse de que su variable TRULY sea const .