2015-02-10 11 views
13

Ho un po 'di codice che non funziona con VS2015, ma funziona con GCC. Sono abbastanza sicuro che il bug sia con Visual Studio ma voglio essere sicuro che la mia comprensione di decltype (auto) sia corretta.chiamato prima del temporaneo deve essere fuori dall'ambito

#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; 
} 

In Visual Studio la stringa restituita da zero_params viene dedotta come riferimento di rvalue. Inoltre il distruttore di quell'oggetto è chiamato all'interno di test1() dove avviene il ritorno dalla chiamata a f (che sembra un luogo ragionevole per distruggere un oggetto & &).

In GCC la stringa restituita non viene dedotta come riferimento di rvalore. Il distruttore è chiamato dopo l'uso nella dichiarazione cout come mi aspetterei.

Specificare il tipo di restituzione come "stringa" anziché decltype (auto) in Visual Studio lo corregge, così come con remove_reference_t sul ritorno di f() all'interno di test1.

La mia aspettativa sarebbe che GCC è corretto come la firma della funzione per zero_params() è stringa, non stringa & & quindi mi aspetto che il non-riferimento a 'bolla' per il tipo di ritorno di test1 se utilizza decltype (auto).

Questa è una valutazione corretta?


EDIT IN RITARDO:

Un altro modo che ho trovato per aggirare il problema con VS2015 è quello di avvolgere la funzione data a TEST1 in un lambda:

cout << test1(zero_params) << endl; 

a:

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

Destra, 'f()' è un valore di provalutazione, quindi 'decltype' dovrebbe dedurre' std :: string' piuttosto che 'std :: string &&'. –

+3

Si prega di presentare una segnalazione di bug su [MS Connect] (https://connect.microsoft.com/VisualStudio/) e inserire il link qui. Questo _really_ deve essere corretto prima che VS2015 passi a RTM se 'decltype (auto)' è destinato ad essere qualcosa di diverso da inutile ... – ildjarn

+0

Sfortunatamente MS Connect mi dice che non sono autorizzato a inviare segnalazioni di bug. Tuttavia, in Visual Studio ho già fatto la cosa migliore - ho inviato un feedback usando la loro 'faccia accigliata', incluso lo screenshot del codice di prova con la descrizione. Sfortunatamente non penso che questo metodo sia rintracciabile? Spero che qualcuno lo passi al dipartimento di destra – qeadz

risposta

2

Quindi based on the comments possiamo concludere:

Il bug è che:

  • Il compilatore avrebbe dovuto dedurre il tipo di ritorno per essere stringa
  • Lo ha effettivamente dedotto come stringa & &
  • Così distrutto il valore prematuramente

Le soluzioni alternative sono:

  • Non utilizzare decltype (auto) per della funzione tipo di ritorno
  • Avvolgere la funzione in un'espressione lambda prima di passare in
+0

Possiamo integrare questi commenti in questa risposta? I commenti sono temporanei –

+1

https://connect.microsoft.com/VisualStudio/feedback/details/1124457/decltype-auto-deducing-wrong-type-in-some-cases –

Problemi correlati