可变参数模板继承下重写虚函数的编译问题
问题描述
我定义了一个通过可变参数模板继承两组基类的类,其中一组基类包含纯虚函数。尝试编写如下代码时编译失败:
template <class T> struct Base { virtual void foo(T t) = 0; }; template <class T> struct Holder { T t; }; template <class... T> struct Child : Base<T>..., Holder<T>... { template <class O> void Base<O>::foo(O t) override { // 此处编译失败 Holder<O>::t = t; } };
编译错误
error: invalid use of incomplete type 'struct Base'
问题原因
原代码的写法不符合C++语法规则:类内部无法通过Base<O>::foo这种形式定义模板化的虚函数重写。同时,模板成员函数不能直接重写非模板的虚函数——每个Base<T>::foo(T)都是独立的非模板纯虚函数,无法通过单个模板函数完成全部重写。
解决方案
可以引入一个中间模板类,针对每个类型T单独实现Base<T>::foo并继承Holder<T>,再让Child继承所有这些中间类,确保每个基类的纯虚函数都被正确实现:
template <class T> struct Base { virtual void foo(T t) = 0; }; template <class T> struct Holder { T t; }; // 中间类:针对单个T实现Base<T>的纯虚函数,同时继承Holder<T> template <class T> struct ChildImpl : Base<T>, Holder<T> { void foo(T t) override { Holder<T>::t = t; } }; // Child继承所有ChildImpl<T>,自动获得所有基类的实现 template <class... T> struct Child : ChildImpl<T>... {};
修改后的代码可以正常编译,每个Base<T>的纯虚函数都被对应的ChildImpl<T>实现,Child作为派生类自然满足所有基类的接口要求。
内容的提问来源于stack exchange,提问作者Leonardo Faria
相关产品推荐
相关产品推荐

