Travis Vitek wrote:
Martin Sebor wrote:
Travis Vitek wrote:
It appears that MSVC doesn't like that you haven't provided
the template parameter types for the specialization of distance().
Looks like a compiler bug. We should report it to Microsoft.
If you don't have one yet, this might be a good opportunity
to set up an account with them and learn how to do it :)
Done. http://tinyurl.com/2u7ave. [14.7.3 p10]
Good. Of course, they immediately closed it as not reproducible
in their internal version with no reference to an existing bug
report so we can only hope that they have a regression test for
it and/or that it doesn't regress between now and the final
release...
It looks like gcc doesn't like how you've put the distance()
specialization into namespace std. It appears that this is
supposed to be legal [14.7.3 p9], but gcc rejects the code.
Yes, it's a gcc 3.2 bug. We reported it back in 2002:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8266
Well I was compiling with gcc 3.4.6, and your testcase is different from
what we have here. I _believe_ that the gcc testcase you provided is
explicitly instantiating the foo() template on int. That is very
different from the problem I'm describing.
I don't really think this is a gcc bug [but it is likely to be a msvc
bug]. From the 2003 version of the standard...
Are you saying you're disagreeing with me?! ;-)
You're right, I misremembered the problem. It's too bad that this
syntax is ill-formed for explicit specialization because the same
syntax is allowed for explicit instantiation:
namespace N { template <class T> void foo (T) { } }
template void N::foo (int); // okay
extern template void N::foo (int); // okay (w/o the above)
template <> void N::foo (long) { } // error
Martin
[14.7.3 p2] An explicit specialization shall be declared in the
namespace
of which the template is a member, or, for member templates, [...] Such
a
declaration may also be a definition. If the declaration is not a
definition, the specialization may be defined later (7.3.1.2).
[7.3.1.2 p2] Members (including explicit specializations of templates
(14.7.3)) of a named namespace can be defined outside that namespace by
explicit qualification (3.4.3.2) of the name being defined, provided
that
the entity being defined was already declared in the namespace and the
declaration appears after the point of declaration in a namespace that
encloses the declaratsion's namespace. [Example:
namespace Q {
namespace V {
void f();
}
void V::f() { /*...*/ } // OK
void V::g() { /*...*/ } // error: g() is not yet a member of V
namespace V {
void g();
}
}
namespace R {
void Q::V::g() { /*...*/ } // error: R doesn't enclose Q
}
]
Travis