2011-07-26 11 views
9

Tworzę szablonową klasę, która jest opakowaniem wokół dowolnego iteratora. Robię operatorowi * w ten sposób:Decltype for return of function

template <typename T> 
class MyIterator { 
public: 
    //... 
    decltype(*T()) operator*() { 
    //... 
    } 
} 

daję decltype na wezwanie do napędu * klasy T, a nawet działa, ale jeśli robi T mieć domyślnego konstruktora to przyzwyczajenie praca.

Czy mimo to można znaleźć zwracany typ funkcji/metody?

Odpowiedz

16

To co std::declval jest dla:

decltype(*std::declval<T>()) operator*() { /* ... */ } 

Jeśli implementacja nie przewiduje std::declval (Visual C++ 2010 nie obejmuje go), można łatwo napisać to sam:

template <typename T> 
typename std::add_rvalue_reference<T>::type declval(); // no definition required 

Od T jest typem iteratora, można również użyć szablonu std::iterator_traits, który nie wymaga żadnego C++ 0x suppor t:

typename std::iterator_traits<T>::reference operator*() { /* ... */ } 
+0

Mój kompilator mówi "nie można używać funkcji declval()!" –

+1

Co dokładnie mówi twój kompilator (i jakiego używasz kompilatora?) Nie można _ODR używać '' declval', ponieważ nie jest zdefiniowane; możesz "użyć" go tylko w kontekstach, w których nie będzie on oceniany, np. w "decltype". –

+0

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/../../../include/c++/4.6.1/type_traits:1134:7: błąd: asercja statyczna nie powiodło się: "declval() nie może być użyty!" –