[Bug c++/57746] rejected valid specialization of member function of class template (I think)
luto at mit dot edu
gcc-bugzilla@gcc.gnu.org
Tue Jul 2 18:30:00 GMT 2013
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.
More information about the Gcc-bugs
mailing list