2015-09-25 16 views
6

considerano i seguenti codici:Perché decltype viene utilizzato nei tipi di restituzione finali?

template< class T1 , class T2> 
auto calc(T1 a , T2 b) 
{ 
    return a + b ; 
} 


template< class T1 , class T2> 
auto calc(T1 a , T2 b) -> decltype(a + b) 
{ 
    return a + b ; 
} 

cosa è la differenza nel secondo codice? Puoi dare qualche esempio dove questo fa la differenza o fa la differenza qui?

risposta

6

Si noti che il tipo di ritorno semplice auto è qualcosa che è solo per C++ 14, mentre il tipo di ritorno finale con decltype è per C++ 11. La differenza arriva quando i riferimenti entrano nell'immagine, ad es. in codice come questo:

#include <type_traits> 

struct Test 
{ 
    int& data; 

    auto calc1() 
    { 
     return data; 
    } 

    auto calc2() -> decltype(data) 
    { 
     return data; 
    } 
}; 

int main() 
{ 
    int x; 
    Test t{x}; 
    static_assert(std::is_same<int, decltype(t.calc1())>::value, ""); 
    static_assert(std::is_same<int&, decltype(t.calc2())>::value, ""); 
} 

Se si desidera rimuovere ->decltype() e mantenere il vostro codice di comportarsi lo stesso, è possibile utilizzare il C++ 14 costrutto decltype(auto)

decltype(auto) calc3() // same as calc2() above 
{ 
    return data; 
} 

che conserva la referenceness del ritorno scrivi pure.

Se già sapete che il vostro tipo di ritorno è un riferimento, basta fare esplicita

auto& calc4() // same as calc2() above 
{ 
    return data; 
} 
+0

Grazie per aver risposto Rex :) Ok, quindi a parte riferimento preservando gli sono gli stessi. Quindi quale si dovrebbe usare o quale è più sicuro da usare? –

+0

dipende da quello che vuoi. Userei 'auto' e' auto & 'per rendere esplicito qual è il riferimento del tipo restituito. Talvolta 'decltype' può avere i suoi vantaggi, ad es. in contesti SFINAE in cui si desidera ritardare l'istanziazione, ecc. [Ma questa è roba avanzata] (http://stackoverflow.com/a/24109800/819272). – TemplateRex

+0

decltype (auto) a volte può essere pericoloso. Ad esempio: decltype (auto) foo() {auto x = 5; ritorno (x); } Perché (x) è un'espressione, il tipo è int e (molte persone circondano restituiscono questa parentesi). Quindi questa funzione restituisce un riferimento a un locale, che è un bug! –

Problemi correlati