(Se sei un C++ 11 pro, passare al paragrafo in grassetto.)Rimuovere riferimento decltype (ritorno T al posto di T & dove T & è il decltype)
Diciamo che voglio scrivere un modello metodo che chiama e restituisce il risultato di un oggetto passato, che tipo è il parametro di modello:
template<ReturnType, T>
ReturnType doSomething(const T & foo) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
Così T
deve avere un metodo ReturnType T::bar() const
al fine di essere utilizzato in una chiamata in questo modo:
struct MyClass {
...
int bar() const;
...
};
...
MyClass object;
int x = doSomething<int, MyClass>(object);
Non abbiamo scrivere MyClass
grazie per digitare la deduzione e la chiamata diventa:
int x = doSomething<int>(object);
ma omettendo <int>
anche i risultati in un errore di compilazione perché il metodo non richiede di tornare int per essere assegnato a x
in seguito (potrebbe restituire char
ad esempio).
In C++ 0x/11 abbiamo la auto
e decltype
con cui possiamo utilizzare per dedurre il tipo di ritorno di un metodo di modello:
template<T>
auto doSomething(const T & foo) -> decltype(foo.bar()) {
return foo.bar(); // EDIT: Might also be an expression introducing a temp val
}
il compilatore ora scoprire qual è il tipo di foo.bar()
è e usa solo questo come tipo di ritorno. Con la nostra classe concreta MyClass
questo sarà un int
e la seguente sarebbe sufficiente:
int x = doSomething(object);
Ora alla mia domanda:
Se MiaClasse definisce bar()
come restituzione di un int&
, il tipo di ritorno di doSomething(object)
sarà anche essere un int&
= decltype(foo.bar())
. Questo è un problema, dal momento che come G ++ ora rispondo che sono restituendo il riferimento a temporaneo.
Come posso risolvere questo? C'è qualcosa come remove_reference
che può essere utilizzato come remove_reference(decltype(foo.bar()))
?
ho pensato di appena dichiarare un metodo di supporto che prende un T&
e restituisce una T
e quindi definire il tipo di ritorno di doSomething
essere decltype(helper(foo.bar()))
. Ma deve esserci un modo migliore, lo sento.
Come si presenta questo problema? Tutto quello che faresti è passare il riferimento. E sì, c'è 'std :: remove_reference :: type'. –
GManNickG
@GManNickG Non voglio un avviso nel mio programma. Voglio compilare con '-Werror -Wall'. Grazie per l'suggerimento 'std :: remove_reference', sapevo di averlo visto prima ma non riuscivo a trovarlo su google durante la ricerca di" C++ 11 tipo di modello di deduzione rimuovi riferimento ", forse la mia ricerca era troppo localizzata :) – leemes
No, sto dicendo che non dovrebbe esserci un avvertimento. Se 'foo.bar()' restituisce un riferimento, dovresti essere in grado di restituirlo altrettanto bene come riferimento. – GManNickG