Consider the following program:
struct A {
template <typename T>
operator T() { return T{}; }
};
int main() {
(void) A{}.operator int(); // (A)
(void) A{}.template operator int(); // (B)
}
(A) is accepted by both GCC and Clang, whereas (B) is accepted only by GCC but rejected by Clang with the following error message:
error: expected template name after 'template' keyword in nested name specifier (void) A{}.template operator int(); // (B) ^~~~~~~~~~~~
Afaict, (B) should be legal, as per [temp.names]/5:
A name prefixed by the keyword
templateshall be a template-id or the name shall refer to a class template or an alias template. [ Note: The keywordtemplatemay not be applied to non-template members of class templates. — end note ] [ Note: As is the case with thetypenameprefix, thetemplateprefix is allowed in cases where it is not strictly necessary; i.e., when the nested-name-specifier or the expression on the left of the->or.is not dependent on a template-parameter, or the use does not appear in the scope of a template. — end note ]
and as the prohibitions governed by [temp.names]/4 does not apply:
The keyword
templateis said to appear at the top level in a qualified-id if it appears outside of a template-argument-list or decltype-specifier. [...] an optional keywordtemplateappearing at the top level is ignored. [...]
and, at most, only state that the keyword should be ignored (but not that the program is ill-formed).
I have not found any clause in [class.conv.fct] or [temp.deduct.conv] that conflicts with this argument.
Question
- Is it legal to prefix explicit access to a conversion function template with the
templatekeyword?
I have tested and repeated the compilers' behaviour above with various GCC and Clang versions for various language standard versions, but for the scope of this question, we may focus on GCC 10.1.0 and Clang 10.0.0 for -std=c++17.