Function templates are not allowed to have C language linkage:
extern "C" {
template<typename T> // error: template with C linkage
void bad_f() {}
}
This is reasonable, as there are potentially multiple instantiations, but, without name mangling, only one symbol that can be exported at the binary level.
However both GCC and Clang accept function templates with non-template C language linkage type:
extern "C" {
using F = void();
}
template<typename T>
F f;
template<typename T>
void f() {}
This is surprising to me. It seems reasonable to assume that, analogously to non-template case, instantiations of f have names with C++ language linkage (i.e. name mangling happens) and types with C language linkage (i.e. C calling convention is used to call them).
Is f declaration actually well-formed C++? If so, does it do what I assume it does?
fis a variable, and as such isn't used for name-mangling. The symbolfwill always have the namef, no matter its type.Fis a function type,F f;declares the function (template)f.