This is an exact duplicate of this question, except that accepted answer is wrong, so I ask it again:
How do you correctly check to see if a given type T
is an iterator?
My attempt at solving it:
// Assume enable_if and is_same are defined
// (hoping for a solution that works for C++03 too)
template<class T>
class is_iterator
{
static char (&test(...))[2];
template<class U>
static typename std::enable_if<
!std::is_same<
typename std::iterator_traits<T>::value_type,
void
>::value,
char
>::type test(U);
public:
static bool const value = sizeof(test(0)) == 1;
};
struct Foo { };
int main()
{
return is_iterator<Foo>::value;
}
on Visual C++ happens to fail with:
...\vc\include\xutility(373)
:
error C2039:'iterator_category'
: is not a member of'Foo'
because iterator_traits
is looking for a definition of value_type
in Foo
, which (obviously) doesn't exist.
I am aware that __if_exists
is a possibility on Visual C++, but I'm looking for a portable solution.