placas para mrelberni microcontroladores libreria isp caracteristicas atmega2560 arquitectura c++ c++11 auto c++14 perfect-forwarding

c++ - para - mrelberni avr



¿Por qué uno nunca debería usar auto && para variables locales? (3)

Mientras T&& se usa con plantillas como referencia de reenvío o referencia universal (como las llama Scott Meyers), he visto que algunos blogs usan auto&& en los ejemplos de código. Creo que el auto sí mismo debería ser suficiente, sin embargo, Herb Sutter en CppCon 2014 dice : Nunca use auto&& para variables locales

¿Porqué es eso?

Al ver todas las respuestas, creo que debería haber pedido la contra. A pesar de las pautas generales de codificación, existen casos de buen uso del uso de auto && dentro de un cuerpo de función para la corrección y el mantenimiento del código.


Admitiré que hay un caso suficientemente bueno cuando desea utilizar el bucle de rango para modificar los contenidos del vector<bool> . Sin embargo, recomendaría leer "On vector<bool> " de Howard Hinnant , el hombre responsable de las referencias de valores.

Aparte de esa aberración, no hay un ejemplo motivador para mostrar el uso de auto&& para variables locales. Cada uso de la variable local de auto&& es un abuso (lo que realmente significa Sutter), excepto las lambdas genéricas. Al motivar me refiero a que no puede escribir código óptimo y correcto (sin conversiones implícitas, etc.) sin auto&& . Puedes usarlo solo porque estabas esperando usar un arma nuclear para matar a un ratón. Consideremos algunos casos que pueden parecer relevantes.

  1. El enunciado de rango basado en rango se define en §6.5.4 para ser equivalente a:

    { auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }

    Ahora esto es puramente teórico. Hagamos un experimento mental y digamos que el compilador hace esto. Los compiladores no son conocidos por la implementación de alto nivel. Incluso si lo hacen, está seguro de que puede obtener una expresión de range-init para gobernarlos a todos.

  2. Mi propio argumento engañoso de reenviar una referencia reenviada a través de múltiples interfaces . Si solo desea reenviar, ¿por qué necesitaría auto&& alias auto&& nombre? Sólo adelante.

  3. ¿Qué pasa si una función devuelve una referencia universal . De Verdad ?? La sobrecarga en el tipo de retorno no está permitida. Puedes hacerlo a través de plantillas. Sin embargo, en una pregunta relacionada, el ejemplo pasa T como argumento de plantilla y también devuelve T Si dices que T puede ser un valor de rvalue o lvalue y quiero usar auto&& , tienes amnesia.

  4. Continuando con 3, incluso si hipotéticamente no sabes si obtienes T o T& de una caja negra (yo evitaría tal caja) no puedes hacer nada significativo sin inferir si es un valor de lvalue o rvalue. Si quieres reenviar solo reenviar.

  5. El problema del bucle for . Déjame generalizarlo. Considere un caso de uso general como for( auto x : {a, b , c}) o for(auto x : getVector()) o casos similares. Desea utilizar for(auto&& b : vb) porque vb puede ser temporal y es posible que también desee modificar el contenido del temporal. En mi sabiduría finita, no entiendo por qué querría modificar los contenidos de un vector temporal o lista. Puede seguir presentando argumentos, ya que el siguiente elemento puede depender del valor anterior modificado, etc., pero puede encontrar una solución óptima sin auto&& . Personalmente creo que la modificación de los contenidos de un temporal sin vincularlo a una const T& debería ser ilegalizada.

  6. El argumento de la plantilla variad . Soñé que si tengo que pelar el primer argumento de var... es posible que quiera usar auto&& o T&& . No creo que ni siquiera esto contenga agua. Avísame si puede haber un caso plausible.

  7. Quiero un auto&& para atar algo . Luego úselo en bucle. Simplemente úselo dentro para bucle.

  8. El argumento del asesino si realmente presenta un caso suficientemente bueno, excepto lambdas: no puede escribir suficientes líneas sin determinarlo o corregirlo como T o T& . De lo contrario, debido a que desea escribir el código óptimo, tendrá un código abultado ... por cada línea que escriba, tendrá que verificar si rvalue hace esto de otra manera si rvalue lo hace. Es mejor utilizar rasgos de tipo al principio para determinar la valuidad r / l.

Por favor, agregue nuevos casos de uso especioso o bueno si encuentra alguno.


Al utilizar auto && solo perdimos el control sobre el almacenamiento variable. Así que nunca deberíamos usar ese tipo de caso. Intenta evitarlo.


Hay casos en los que necesita un auto&& como local, considere:

vector<bool> vb { true, false, true }; for( auto&& b : vb ) b = !b;

Aquí, un auto y no lo haría. (si el vector<bool> es especializado)

Sin embargo, la razón habitual por la que usa && junto con la deducción de tipo
(es decir, una referencia de reenvío) es porque no sabe o no le importa el
Tipo exacto, solo vas a reenviarlo.

El término ''referencia universal'' es un poco engañoso, no debes usar
universalmente, de ahí su nombre cambiante a ''referencia de reenvío''

Tenga en cuenta que && no se utiliza con la deducción de tipo es una referencia de valor, una diferente
cosa por completo.