
"Thomas Witt" <witt@acm.org> wrote in message news:cgal5p$lb4$1@sea.gmane.org...
How do you implement that?
Thomas, I'm using the SFINAE principle. I have two member functions called 'test' in 'struct detail::is_iterator_impl', where one of them is a template: static char (& test(...))[2]; template <typename T> static char test( T *, type_tag<typename T::value_type> * = 0, type_tag<typename T::reference> * = 0, type_tag<typename T::pointer> * = 0, type_tag<typename T::difference_type> * = 0, type_tag<typename T::iterator_category> * = 0, star_op_tag<T, &T::operator* > * = 0, arrow_op_tag<T, &T::operator-> > * = 0, prefix_op_tag<T, &T::operator++ > * = 0, postfix_op_tag<T, &T::operator++ > * = 0 ); Then in 'is_iterator', I define 'value' as follows: BOOST_STATIC_CONSTANT( value_type, value = sizeof(detail::is_iterator_impl::test((T *) 0)) == 1 ); Thus, if T meets the requirements for an iterator, argument deduction succeeds and an instantiation of the 'test' function template is added to the set of candidate functions. And since T * is a better match than ..., this function is the one that gets chosen during overload resolution. Then 'value' evaluates to true. Otherwise, argument deduction fails, and the first function gets chosen instead because it's the only candidate. Then 'value' evaluates to false. Of course, this implementation will not work for pointers, so I provide a partial template specialization for this case. (Please see my response to Jonathan for details.) As an alternative, I considered using Boost iterator traits instead of constructs like 'typename T::value_type', since iterator traits handle pointers correctly. But iterator traits don't include operators, so a partial template specialization would still be required. Lastly, Jonathan pointed out that these operators can be implemented as non-member functions. I am working on a solution that will work when this is the case. Thanks, Alex