c++ auto c++14 decltype visual-studio-2015

c++ - el destructor llamado antes temporal debe estar fuera del alcance



auto c++14 (1)

Entonces, según los comentarios , podemos concluir:

El error es que:

  • El compilador debería haber deducido el tipo de retorno para ser una cadena
  • De hecho, lo dedujo como una cadena &&
  • Por lo tanto, destruyó el valor prematuramente

Las soluciones son:

  • No use decltype (auto) para el tipo de retorno de la función
  • Envuelva la función en una expresión lambda antes de pasarla

Tengo un poco de código que falla bajo VS2015, pero funciona bajo GCC. Estoy bastante seguro de que el error está con Visual Studio, pero quiero estar seguro de que mi comprensión de decltype (automático) es correcta.

#include <iostream> using namespace std; string zero_params() { return "zero_params called."; } template< typename F > auto test1( F f ) -> decltype(auto) { return f(); } int main() { cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl; cout << test1(zero_params) << endl; cout << "Done!" << endl; return 0; }

En Visual Studio, la cadena devuelta por zero_params se deduce como una referencia de valor r. Además, el destructor de ese objeto se llama inside test1 () donde ocurre el retorno de la llamada a f (que parece un lugar razonable para destruir un objeto &&).

En GCC, la cadena devuelta no se deduce como una referencia de valor real. El destructor se llama después de su uso en la instrucción cout como era de esperar.

Al especificar que el tipo de devolución sea ''cadena'' en lugar de decltype (automático) en Visual Studio, se corrige, al igual que con remove_reference_t en el retorno de f () dentro de test1.

Mi expectativa sería que GCC es correcto ya que la firma de la función para zero_params () es cadena, no cadena &&, así que esperaría que la no referencia a ''burbuja'' para el tipo de retorno de test1 si usa decltype (auto).

¿Es esta una evaluación correcta?

EDICION TARDE:

Otra forma que he encontrado para evitar esto con VS2015 es ajustar la función dada a test1 en una lambda:

cout << test1(zero_params) << endl;

a:

cout << test1( [](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); } ) << endl;