[Bug c++/40497] invalid std::next / std::prev declaration

rguenth at gcc dot gnu dot org gcc-bugzilla@gcc.gnu.org
Sun Jun 21 10:38:00 GMT 2009



------- Comment #14 from rguenth at gcc dot gnu dot org  2009-06-21 10:38 -------
Testcase w/o std=c++0x:

template <typename I> struct T { typedef typename I::d d; };
template <typename I> I next(I __x, typename T<I>::d __n = 1);
namespace X
{
  class C { };
  template<class T> void next(T) { }
}
int main()
{
  X::C c;
  next(c);
}

but EDG rejects this also:

t.C(1): error: class "X::C" has no member "d"
  template <typename I> struct T { typedef typename I::d d; };
                                                       ^
          detected during instantiation of class "T<I> [with I=X::C]" at line
11

t.C(11): error: more than one instance of function template "next" matches the
argument list:
            function template "void X::next(T)"
            function template "I next(I, T<I>::d)"
            argument types are: (X::C)
    next(c);
    ^

I'm not sure SFINAE applies here as the substitution T<I> succeeds.

With the 'typename' removed in the decl for next we get

t.C(2): error: nontype "T<I>::d [with I=I]" is not a type name
  template <typename I> I next(I __x, T<I>::d __n = 1);
                                      ^

t.C(11): error: more than one instance of function template "next" matches the
argument list:
            function template "void X::next(T)"
            function template "I next(I, <error-type>)"
            argument types are: (X::C)
    next(c);
    ^

with

template <typename I> I next(typename T<I>::d __n);

we finally get SFINAE and X::next is chosen.

The issue here seems to be that the default value for the argument somehow
gets in the way and so the 2nd argument isn't checked properly?

So an implementation workaround would be to use overloading for the
default argument case like

template <typename I> I next(I __x, typename T<I>::d __n);
template <typename I> I next(I __x);

with the first arg obfuscated so that SFINAE applies,
typename iterator_traits<_InputIterator>::_InputIterator

or something like this?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40497



More information about the Gcc-bugs mailing list