Al crear variables locales, ¿es correcto usar (const) auto&
o auto
?
p.ej:
SomeClass object;
const auto result = object.SomeMethod();
o const auto& result = object.SomeMethod();
Donde SomeMethod () devuelve un valor no primitivo, tal vez otro tipo definido por el usuario. Tengo entendido que const auto& result
es correcto ya que el resultado devuelto por SomeMethod () llamaría al constructor de copia para el tipo devuelto. Por favor, corríjame si estoy equivocado.
¿Qué pasa con los tipos primitivos? Supongo que const auto sum = 1 + 2;
es correcto.
¿Esto también se aplica al rango basado en bucles?
for(const auto& object : objects)
auto
funciona (excepto en el caso peculiar deinitializer_list
s, que son no deducido en un contexto de plantilla), luegoauto
escriba deducción.Respuestas:
auto
yauto &&
cubren la mayoría de los casos:Úselo
auto
cuando necesite una copia local. Esto nunca producirá una referencia. El constructor de copia (o movimiento) debe existir, pero es posible que no se llame debido a la optimización de elisión de copia .Úselo
auto &&
cuando no le importe si el objeto es local o no. Técnicamente, esto siempre producirá una referencia, pero si el inicializador es temporal (por ejemplo, la función regresa por valor), se comportará esencialmente como su propio objeto local.Además,
auto &&
tampoco garantiza que el objeto sea modificable. Dado unconst
objeto o referencia, lo deduciráconst
. Sin embargo, a menudo se asume la modificabilidad, dado el contexto específico.auto &
yauto const &
son un poco más específicos:auto &
garantiza que está compartiendo la variable con otra cosa. Siempre es una referencia y nunca temporal.auto const &
es similarauto &&
, pero proporciona acceso de solo lectura.No hay diferencia.
Si. Aplicando los principios anteriores,
auto &&
para la capacidad de modificar y descartar valores de la secuencia dentro del bucle. (Es decir, a menos que el contenedor proporcione una vista de solo lectura, por ejemplostd::initializer_list
, en cuyo caso será efectivamente unaauto const &
.)auto &
para modificar los valores de la secuencia de una manera significativa.auto const &
para acceso de solo lectura.auto
para trabajar con copias (modificables).También lo mencionas
auto const
sin referencia. Esto funciona, pero no se usa con mucha frecuencia porque rara vez hay una ventaja en el acceso de solo lectura a algo que ya posee.fuente
auto&
parece ser una buena elección. Peroconst auto&
utilícelo cuando desee agregar constness que aún no está allí.auto&&
es para reenvío, que creo que ocurre con más frecuencia de lo que piensa Sutter. Por ejemplo, es posible que desee almacenar un valor de retornoauto&&
y luego "reenviarlo" a dos cosas, como std :: cout para ver el valor de depuración y también pasarlo a alguna otra función. Solía usar auto && con más frecuencia, pero me ha mordido una o dos veces cuando hacía cosas inesperadas. ¡Ojalá me diera más cuenta de lo que salió mal!auto&&
está relacionado con una característica de lenguaje faltante, que debería permitir que cualquier declaración se divida en declaraciones más pequeñas. La parte que falta es la extensión de la vida útil ... Me esforcé un poco en solucionar esto, pero nadie se dio cuenta. No pongas demasiado valor en los expertos :)Sí, es correcto de usar
auto
yauto&
para variables locales. Al obtener el tipo de retorno de una función, también es correcto usarloauto&
. Esto también se aplica al rango basado en bucles for.Las reglas generales de uso
auto
son:auto x
cuándo desea trabajar con copias.auto &x
cuándo desea trabajar con elementos originales y puede modificarlos.auto const &x
cuándo desea trabajar con elementos originales y no los modificará.Puede leer más sobre el especificador automático aquí .
fuente
auto
utiliza el mismo mecanismo de deducción de tipos que las plantillas, la única excepción que conozco es la de las listas brace-init, que se deducenauto
comostd::initializer_list
, pero no se deducen en un contexto de plantilla.auto x = expression;
funciona quitando primero todos los calificadores de referencia y cv del tipo de la expresión del lado derecho, luego haciendo coincidir el tipo. Por ejemplo, si tiene
const int& f(){...}
,auto x = f();
deducex
comoint
y noconst int&
.La otra forma,
auto& x = expression
no elimina los calificadores cv, por lo que, utilizando el ejemplo anterior,
auto& x = f()
deducex
comoconst int&
. Las otras combinaciones solo agregan calificadores de cv.Si desea que su tipo siempre se deduzca con calificadores cv-ref, use el infame
decltype(auto)
en C ++ 14, que usa lasdecltype
reglas de deducción de tipos.Entonces, en pocas palabras, si desea copias, use
auto
, si desea referencias, useauto&
. Úseloconst
siempre que lo deseeconst
.EDITAR Hay un caso de uso adicional,
auto&& x = expression;
que utiliza las reglas de contracción de referencias, al igual que en el caso de reenviar referencias en el código de plantilla. Si
expression
es un lvalue, entoncesx
es una referencia de lvalue con los calificadores cv deexpression
. Siexpression
es un rvalue, entoncesx
es una referencia de rvalue.fuente
rvalues
. ¿Existe alguna forma sencilla de realizar la prueba? ¿Y cómo se puede tener un rvalue calificado de cv? En la función return cv se descarta.auto && x = std::move< const int >( 5 );
declararánint const && x
, aunque rara vez se utilizan.Si. El auto no es más que un tipo deducido por el compilador, así que use referencias donde normalmente usaría referencias y copias locales (automáticas) donde normalmente usaría copias locales. El uso o no de una referencia es independiente de la deducción de tipo.
¿Legal? Sí, con la const. ¿Mejores prácticas? Probablemente no, no. Al menos, no con C ++ 11. Especialmente no, si el valor devuelto por SomeMethod () ya es temporal. Querrá aprender sobre la semántica de movimiento de C ++ 11, la elisión de copias y la optimización del valor de retorno: https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by- valor/
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=199
https://isocpp.org/wiki/faq/ctors#return-by-value-optimization
Sí, esto está bien.
Sí, esto también está bien. Escribo este tipo de código en el trabajo todo el tiempo.
fuente