Reputation: 461
I'm trying to reuse existing templated functions from a namespace in my own namespace and explicitly instantiate them for code coverage reasons.
The following code compiles with gcc 9.3 but does not compile with clang 10.0.0
namespace bar {
template<typename T>
T func(T arg){ return arg;};
}
namespace foo {
using bar::func;
}
template int foo::func<int>(int);
int main()
{ }
View example here
If i instantiate the template function as
template int bar::func<int>(int);
clang compiles as well. But this is not what i want.
Is it possible to explicitly instantiate a template function across namespaces with clang?
Why do gcc and clang give different results?
Upvotes: 4
Views: 1756
Reputation: 170074
You can't do that, I'm afraid. Clang is correct.
[temp.explicit]
2 The syntax for explicit instantiation is:
explicit-instantiation: externopt template declaration4 If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall include a simple-template-id; otherwise, the declaration shall be a simple-declaration whose init-declarator-list comprises a single init-declarator that does not have an initializer.
This paragraph tells us that the bit after the template
keyword must be both syntactically and semantically a valid declaration for something (and must not contain an initializer, which isn't relevant here). A declaration has several parts, but the one of interest here is the declarator part of the declaration.
About that we have the following paragraph
[dcl.meaning] (emphasis mine)
1 A declarator contains exactly one declarator-id; it names the identifier that is declared. An unqualified-id occurring in a declarator-id shall be a simple identifier except for the declaration of some special functions ([class.ctor], [class.conv], [class.dtor], [over.oper]) and for the declaration of template specializations or partial specializations ([temp.spec]). When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers (or, in the case of a namespace, of an element of the inline namespace set of that namespace ([namespace.def])) or to a specialization thereof; the member shall not merely have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id.
Since your declarator-id in the explicit template instantiation is foo::func
, it does not follow the rule laid out in the sentence I marked in bold. That makes your attempt at explicit instantiation ill-formed.
GCC should have rejected your attempt too.
Upvotes: 3