非模板函数使用模板消除歧义符的GCC合规性问询
GCC接受非模板函数前加
template关键字是否合规? 先看这段代码:
template <typename U> struct Bar{ void setNumber(int) {} }; template <int N> struct Asd : public Bar<Asd<N>>{ void doSomething(); }; template<int N> inline void Asd<N>::doSomething() { this->template setNumber(N); } int main() { Asd<42> obj; obj.doSomething(); }
这段代码能被GCC(包括13.1版本及主干版本)编译通过,但Clang会直接拒绝。问题在于setNumber明明不是模板函数,调用时却加了template消歧义符,下面结合C++标准条款明确GCC的行为是否属于bug。
根据C++标准的具体条款:
- [temp.names]/4(C++20及后续版本)规定:
template消歧义符不得出现在不必要的语境中(见6.5.1)。
- 配套的**[expr.prim.id]/3**补充说明:
只有当名称是模板名,或者前面带有
template关键字时,后面跟<的名称才会被当作模板id处理。
回到代码里的this->template setNumber(N);,这里的setNumber是基类Bar<Asd<N>>的非模板成员函数,调用它完全不需要template消歧义符——我们根本没有把它当作模板来特化(调用语句里也没有<>)。在这种非必要语境下使用template关键字,属于违反标准的格式错误,因此Clang拒绝编译是正确的,GCC接受这段代码属于bug。
此前在GCC bugzilla搜索“disambiguator”,未找到与该问题相关的bug记录。
内容的提问来源于stack exchange,提问作者Bulletmagnet
相关产品推荐
相关产品推荐

