Re: work round for std::distance's long arm.
Louis Lavery wrote:
Without the nested typedefs the following fails to compile
under vc7 and gcc 3.2.
/* distance.cpp */
#include <iterator>
#include <list>
namespace user
{
template<typename Iter,typename Dist> struct Cursor
{
#if 0
typedef void iterator_category;
typedef void difference_type;
typedef void value_type;
typedef void reference;
typedef void pointer;
#endif
};
template<typename Iter,typename Dist>
Dist distance(
Cursor<Iter,Dist> const&,
Cursor<Iter,Dist> const&)
{
return 0;
}
}
int main()
{
user::Cursor<std::list<int>::iterator,int> cur;
distance(cur,cur); // XXX
return 0;
}
/* distance.cpp end */
Because Cursor's instantiated with an iterator from std,
I guess what happens (at XXX) is the compiler looks in
namespace std and sees something like...
template<class Iter>
typename iterator_traits<Iter>::difference_type
distance<Iter,Iter) {...}
...and so needs to instantiate iterator_traits<Cursor> to get
the return type. But the default iterator_traits requires its
parameter to have nested typedefs for iterator_category etc.
Have I got that right?
The distance() function call does indeed call std::distance(). However,
iterator_traits is not instantiated in order to find std::distance's
return type (the compiler can figure that out without instantiating
iterator_traits). Instead it is the implementation of std::distance()
that relies on the iterators' nested typedefs when figuring out the
best way to calculate the distance between them.
This being the case, what's the best work round?
If the program intends to call std::distance(), then there is no
workaround other to pass iterator types of the kind that
std::distance() expects. On the other hand, if this program is calling
std::distance() by mistake and really intends to be calling
user::distance(), then the function call has to be more explicit:
user::distance( cur, cur );
I know I can use void typedefs as above but that adds noise.
The typedefs may be "noise" for a program calling user::distance() -
but are a prerequisite for one (such as this program in its current
form) calling std::distance().
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]