C++中派生类如何特化模板基类的模板方法Foo?
问题描述
我有一个带模板方法Foo的模板基类Bar,还有一个用于限定强类型枚举的conceptEnumClass。尝试创建派生类Deriving,并为特定枚举值特化Foo方法,但编译失败,错误提示:template-id 'Foo<A::a, B::b>' for 'void Deriving::Foo()' does not match any template declaration。
原代码如下:
template<typename T> concept EnumClass = is_scoped_enum<T>::value; // 判断是否为强类型枚举 template <EnumClass ECA, EnumClass ECB> class Bar { template<ECA ECAval, ECB ECBval> void Foo(); }; enum class A{a}; enum class B{b}; class Deriving : public Bar<A, B> {}; template<> void Deriving::Foo<A::a, B::b>() {/* 实现代码 */}
错误原因
Deriving继承的是模板类Bar的实例化版本Bar<A,B>,但Foo是基类Bar的成员函数模板,并非派生类Deriving自身定义的模板成员。直接尝试特化Deriving::Foo时,编译器找不到对应的模板声明,自然会报错。
解决方案
有两种可行的修改方式:
方式一:直接特化基类实例的成员函数模板
直接针对Bar<A,B>的Foo模板进行特化,派生类继承后可直接使用该特化版本:
template<typename T> concept EnumClass = is_scoped_enum<T>::value; template <EnumClass ECA, EnumClass ECB> class Bar { public: // 需将Foo设为public/protected,否则派生类无法访问 template<ECA ECAval, ECB ECBval> void Foo(); }; enum class A{a}; enum class B{b}; // 特化Bar<A,B>的Foo<A::a, B::b> template<> void Bar<A,B>::Foo<A::a, B::b>() { // 实现逻辑 } class Deriving : public Bar<A, B> {};
方式二:在派生类中重新声明模板并特化
如果希望特化版本归属派生类,可以在Deriving中重新声明与基类签名一致的Foo模板,再进行特化:
template<typename T> concept EnumClass = is_scoped_enum<T>::value; template <EnumClass ECA, EnumClass ECB> class Bar { public: template<ECA ECAval, ECB ECBval> void Foo(); }; enum class A{a}; enum class B{b}; class Deriving : public Bar<A, B> { public: // 重新声明与基类匹配的模板函数 template<A ECAval, B ECBval> void Foo(); }; // 特化派生类的Foo模板 template<> void Deriving::Foo<A::a, B::b>() { // 实现逻辑 }
内容的提问来源于stack exchange,提问作者Omer Kawaz
相关产品推荐
相关产品推荐

