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

--- Comment #6 from Andy Lutomirski <luto at mit dot edu> ---
Jonathan Wakely wrote in comment #4:
> (In reply to Andy Lutomirski from comment #4)
>> [temp.explicit].4 says "A declaration of [list including member function]
>> ... A definition of [list not including member function]".  If definitions
>> were intended to be declarations in this context, then the second part would
>> be redundant, I think.
>
> That doesn't follow at all. The second part describes different types of
> entities that have different requirements.
>
> For the first list an explicit instantiation must follow a declaration (and a
> definition also counts as a declaration) but for the second list an explicit
> instantiation must follow a definition, a declaration is not sufficient.

Ugh.  In that case, [temp.explicit].4 is irrelevant.  I guess it means that, if
you explicitly instantiate something, then a declaration and/or definition must
happen before that instantiation, and it probably doesn't mean that a
declaration and/or definition can't follow that explicit instantiation.

>> Regardless, the interesting case is:
>> 
>> template<typename T>
>> struct X
>> {
>>   static int val;
>>   static void func();
>> };
>> 
>> // optionally: extern template struct X<int>;
>> 
>> void something()
>> {
>>   X<int>::func();
>> }
>> 
>> in one file and
>> 
>> struct X
>> {
>>   static int val;
>>   static void func();
>> };
>> 
>> template<> void X<int>::func() {}
>> 
>> in another.  I don't think this is an odr violation, since there is only one
>> definition of anything that could be confused with X<int>::func.  g++ will
>> happily compile and link it (without the extern template bit) and it will
>> work.  It is supposed to?  Could a conforming compiler mangle the
>> specialized version of func differently?
>
> Isn't this ill-formed, with no diagnostic required, by both [temp] p6 and
> [temp.expl.spec] p6?

...so this proves that I know considerably less about C++ templates than I
thought I did.  Apparently even a translation unit containing exactly:

template<typename T> void func();

void caller()
{
  func<int>();
}

is ill-formed.  I wonder why.  g++ and clang++ both accept it, I think (from
memory) that MSVC accepts it as well, and I wouldn't be surprised if there are
quite a few libraries that rely on this behavior.

Reply via email to