entrar aquí unos años más tarde, en la que C++ y C++ 11 14 hacen que sea mucho más fácil de hacer tales cosas. Un iterator es, en su núcleo, algo que es dereferencable, incrementable. Si es un input iterator, entonces también es comparable. Vamos con esto último, ya que se parece a lo que quieres.
La versión más simple sería utilizar void_t
: caso
template <typename... >
using void_t = void;
Base:
template <typename T, typename = void>
struct is_input_iterator : std::false_type { };
caso especialización Válido:
template <typename T>
struct is_input_iterator<T,
void_t<decltype(++std::declval<T&>()), // incrementable,
decltype(*std::declval<T&>()), // dereferencable,
decltype(std::declval<T&>() == std::declval<T&>())>> // comparable
: std::true_type { };
Alias:
template <typename T>
using is_input_iterator_t = typename is_input_iterator<T>::type;
No necesita confiar en iterator_category
o utilizar el tedioso estilo C++ 03 para verificar cosas usando la resolución de sobrecarga. Expresión SFINAE es donde está.
Como señala el Sr. Wakely en los comentarios, [iterator.traits] requiere que:
se requiere que si Iterator
es el tipo de un iterador, los tipos
iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type
iterator_traits<Iterator>::iterator_category
se define como el tipo de diferencia del iterador, el tipo de valor y la categoría de iterador, respectivamente.
Así podemos definir nuestro rasgo iterador simplemente comprobar que:
template <class T, class = void>
struct is_iterator : std::false_type { };
template <class T>
struct is_iterator<T, void_t<
typename std::iterator_traits<T>::iterator_category
>> : std::true_type { };
Si iterator_traits<T>::iterator_category
está enfermo formados, a continuación, T
no es un iterador.
supongo Concept la comprobación podría ayudarte. No es fácil sin embargo. –
¿Realmente ** necesita ** saber? ¿Qué vas a hacer cuando lo descubras? ¿Sería suficiente probar que el tipo implementa, digamos, el operador * y el operador ++? –
@Karl Knechtel: Mi objetivo es: si el tipo T tiene operator * y operator ++ (incluidos los operadores incorporados), entonces is_iterator :: value no será cero. –
xmllmx