This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/15910] can't compile self defined void distance(std::vector<T>, std::vector<T>)
- From: "giovannibajo at libero dot it" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 11 Jun 2004 00:01:48 -0000
- Subject: [Bug libstdc++/15910] can't compile self defined void distance(std::vector<T>, std::vector<T>)
- References: <20040610143911.15910.king.benjamin@mh-hannover.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From giovannibajo at libero dot it 2004-06-11 00:01 -------
Subject: Re: can't compile self defined void distance(std::vector<T>, std::vector<T>)
bangerth at dealii dot org wrote:
> Alright, so here things go: [...]
Thank you for the perfect analysys!
> I think there is not much we can do about this -- what the user would
> like is of course that std::distance is rejected right away, but we
> could
> only do this by putting more checks into the function signature (via
> SFINAE) that the type that was passed is indeed an iterator.
> Given the wide variability of iterator types, I fear that there is not
> very much we can do about things at this point.
Something like this could work, but it's totally untested:
/****/
// it's an iterator if it has a nested type called iterator_category
template <class T> struct is_iterator
{
typedef char yes[1];
typedef char no[2];
template <class T> yes test(typename T::iterator_category* );
template <class T> no test(...);
enum { result = (sizeof(test<T>(0)) == sizeof(yes)) };
};
// or if it's a pointer
template <class T>
struct is_iterator<T*> { enum { result = 1 }; };
/****/
// handy SFINAE to be used in return types
template <bool B, class T> struct enable_if {};
template <class T> struct enable_if<true, T> { typedef T type; }
/****/
namespace std{
template<typename _InputIterator>
inline
typename enable_if< typename is_iterator<_InputIterator>::result,
typename iterator_traits<_InputIterator>::difference_type >::type
distance(_InputIterator __first, _InputIterator __last)
{
.....
}
}
> Giovanni, are you convinced that this isn't really a gcc problem?
Well, let's put in this way: when I look at the testcase for this bug, it
strikes me VERY ODD that it is not valid C++ code. If you name distance as
distance2 it works. The name clash between ::distance() and std::distance()
should not happen, it is not meant to happen (this is why there is a namespace
std in the first place!), and it is just a side effect of the complexity of the
language rules.
So yes, I think it is a problem in GCC, and I reckon it can be fixed pretty
much like I have shown.
Giovanni Bajo
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15910