Strange iterator_traits of iterator_facade

Hello all,
I have a class that is templated on an iterator type. As it only works
with bidirectional and random access iterators, I thought I would impose
that as follows:
template<typename T> class A
{
A() { checkIterator(std::iterator_traits<T>::iterator_category()); };
template<typename Tag> void checkIterator( Tag );
void checkIterator( std::bidirectional_iterator_tag ) {};
void checkIterator( std::random_access_iterator_tag ) {};
void checkIterator( boost::random_access_traversal_tag ) {};
};
This works when T is a standard iterator but not when it's one of my
iterator_facade subclasses. For example:
class const_iterator : public iterator_facade

AMDG Swerts, Benjamin wrote:
I have a class that is templated on an iterator type. As it only works with bidirectional and random access iterators, I thought I would impose that as follows:
template<typename T> class A { A() { checkIterator(std::iterator_traits<T>::iterator_category()); };
template<typename Tag> void checkIterator( Tag ); void checkIterator( std::bidirectional_iterator_tag ) {}; void checkIterator( std::random_access_iterator_tag ) {}; void checkIterator( boost::random_access_traversal_tag ) {}; };
This works when T is a standard iterator but not when it's one of my iterator_facade subclasses. For example:
class const_iterator : public iterator_facade
When using this class with A
I get a linker error because the checkIterator function is called with: boost::detail::iterator_category_with_traversal
I certainly cannot add a specialization of checkIterator with this tag to class A. Could anyone shed some light on this problem? I'm working with Boost 1.39.0 on MSVC2008SP1.
Try just having a single overload: void checkIterator(std::bidirectional_iterator_tag) {} In Christ, Steven Watanabe

AMDG
Swerts, Benjamin wrote:
I have a class that is templated on an iterator type. As it only works with bidirectional and random access iterators, I thought I would impose that as follows:
template<typename T> class A { A() { checkIterator(std::iterator_traits<T>::iterator_category()); };
template<typename Tag> void checkIterator( Tag ); void checkIterator( std::bidirectional_iterator_tag ) {}; void checkIterator( std::random_access_iterator_tag ) {}; void checkIterator( boost::random_access_traversal_tag ) {}; };
This works when T is a standard iterator but not when it's one of my iterator_facade subclasses. For example:
class const_iterator : public iterator_facade
When using this class with A
I get a linker error because the checkIterator function is called with: boost::detail::iterator_category_with_traversal
I certainly cannot add a specialization of checkIterator with this tag to class A. Could anyone shed some light on this problem? I'm working with Boost 1.39.0 on MSVC2008SP1.
Try just having a single overload:
void checkIterator(std::bidirectional_iterator_tag) {}
In Christ, Steven Watanabe
Unfortunately that doesn't work. Now it complains also about regular random access iterators. Tags are apparently not automatically converted into each other. Maybe I should keep the single templated checkIterator function and determine the type of the tag using some MPL magic? I doubt I could come up with such a solution myself as I never used it before. I made some tests with boost::mpl::iterator_category but it looks like the iterator should typedef 'category' instead of 'iterator_category'. Thanks for the help so far. Greets, Ben

AMDG Swerts, Benjamin wrote:
Swerts, Benjamin wrote:
template<typename Tag> void checkIterator( Tag ); void checkIterator( std::bidirectional_iterator_tag ) {}; void checkIterator( std::random_access_iterator_tag ) {}; void checkIterator( boost::random_access_traversal_tag ) {}; };
Try just having a single overload:
void checkIterator(std::bidirectional_iterator_tag) {}
Unfortunately that doesn't work. Now it complains also about regular random access iterators. Tags are apparently not automatically converted into each other.
Yes they can. #include <iterator> void checkIterator(std::bidirectional_iterator_tag) {} int main() { checkIterator(std::random_access_iterator_tag()); }
Maybe I should keep the single templated checkIterator function and determine the type of the tag using some MPL magic? I doubt I could come up with such a solution myself as I never used it before. I made some tests with boost::mpl::iterator_category but it looks like the iterator should typedef 'category' instead of 'iterator_category'.
Did you leave the templated overload? If you did, it will usually win in overload resolution. Do you really want a link error instead of a compiler error? In Christ, Steven Watanabe
participants (2)
-
Steven Watanabe
-
Swerts, Benjamin