2011-07-26 11 views
9

Estoy creando una clase de plantilla que es un envoltorio alrededor de cualquier iterador. Estoy haciendo el operador * de esta manera:Decltype para el retorno de una función

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

Doy decltype una invocación al operador * de la clase T, y aún funciona, pero si T tampoco tienen constructor por defecto que no funcionará.

¿Hay alguna forma de averiguar el tipo devuelto de una función/método?

Respuesta

16

Esto es lo que std::declval es para:

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

Si su aplicación no proporciona std::declval (Visual C++ 2010 no lo incluye), que fácilmente puede escribir usted mismo:

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

Dado que T es un tipo de iterador, también puede usar la plantilla std::iterator_traits, que no requiere ningún soporte de C++ 0x t:

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

Mi compilador dice "declval() no se debe utilizar!" –

+1

¿Qué dice exactamente tu compilador (y qué compilador estás utilizando?) No puedes usar _ODR_ 'declval' porque no está definido; solo puede "usarlo" en contextos en los que no se evaluará, p. en un 'decltype'. –

+0

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/../../../../include/c++/4.6.1/type_traits:1134:7: error: static assertion error: "declval() no se debe utilizar!" –

Cuestiones relacionadas