GCC 13.1.0是否存在Bug?基类为模板时派生类同名模板的隐藏与特化问题
这是GCC 13.1.0的Bug吗?如何规避?
这确实是GCC 13.1.0的Bug。根据C++的名称隐藏规则,派生类s1中声明的类模板foo应当完全隐藏基类s0<int>中的同名模板,GCC错误地将派生类内的foo声明解读为基类模板的偏特化。而Clang 18.0.2、MSVC 19.41的正常编译表现,以及s0为非模板类时GCC自身的正确行为,都验证了这是GCC的解析错误。
问题代码如下:
template< class X > struct s0 { template< class T > struct foo; }; struct s1 : public s0<int> { // 本应是全新的类模板,隐藏基类的foo template< class T > struct foo; // GCC报错:partial specialization 's0<int>::foo<T>' declared 'friend' template< class T > friend struct foo; };
可行的规避方案
方案一:显式限定友元的作用域
在友元声明中明确指定foo属于s1,让GCC正确识别这是派生类自身的模板:template< class X > struct s0 { template< class T > struct foo; }; struct s1 : public s0<int> { template< class T > struct foo; // 显式限定为s1的foo模板 template< class T > friend struct s1::foo; };方案二:提前声明派生类的
foo模板
在s1类外部先声明s1::foo,再在类内定义并声明友元,绕过GCC的错误解析逻辑:template< class X > struct s0 { template< class T > struct foo; }; // 提前声明s1及其foo模板 struct s1; template<class T> struct s1::foo; struct s1 : public s0<int> { template< class T > struct foo; template< class T > friend struct foo; };方案三:使用别名明确区分
在派生类内部给自身的foo模板定义一个别名,再基于别名声明友元,避免GCC混淆基类与派生类的同名模板:template< class X > struct s0 { template< class T > struct foo; }; struct s1 : public s0<int> { template< class T > struct foo; // 定义别名指向自身的foo template<class T> using self_foo = foo<T>; template< class T > friend struct self_foo; };
内容的提问来源于stack exchange,提问作者Louis Semprini
相关产品推荐
相关产品推荐

