如何明确地实例化基本模板类?

gex*_*ide 9 c++ inheritance templates explicit-instantiation

这个问题正在考虑模板类的明确实例化.

考虑B<T>从另一个模板类派生的模板类A<T>.我想明确地实例化,B<T>因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的.当然,也会调用从中继承的方法A<T>,因此它们也必须实例化.

似乎C++在显式实例化模板类时不会实例化基类,如本问题所述: C++类模板的显式实例化是否实例化依赖基类? 例:

template<typename T>
class A{ void foo(){...} };

template<typename T>
class B : public A<T> {}

template class B<int>; // This will NOT instanciate A<int>::foo()!!!
Run Code Online (Sandbox Code Playgroud)

当然,我还需要实现所有基类.但是,我不想用此负担客户端代码,因为类层次结构可能非常深.考虑涉及10个或更多模板类的类层次结构.不应该敦促客户编写10个显式模板实例.这不仅仅是大量的写​​作; 当我向类层次结构引入更改时,它也会中断.

相反,我想以某种方式实现无论何时实现B<T>,那么它的所有基类都是如此.我尝试简单地在B本身中实现基类,如下所示:

template<typename T>
class B : public A<T> {
    template class A<T>; // Does not compile!
}
Run Code Online (Sandbox Code Playgroud)

但这不编译.还有其他方法可以实现这一目标吗?

Ola*_*del 2

也许不优雅但至少可行:提供一个宏来实例化模板并要求用户使用该宏而不是手动实例化:

// in A.hpp
#define INSTANTIATE_A(T) template class A<T>;

// in B.hpp
#define INSTANTIATE_B(T) \
    INSTANTIATE_A(T)     \
    template class B<T>;
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢“污染”类接口而不是强制使用实例化宏:添加一个protected调用模板和基类中版本的所有其他成员函数的成员。例子:

template<typename T>
class A
{
    void foo() {...}
protected:
    void instantiate() { foo(); }
};

template<typename T>
class B : public A<T>
{
    void bar() {...}
protected:
    void instantiate() { A<T>::instantiate(); bar(); }
};

template class B<int>; // Now works as expected
Run Code Online (Sandbox Code Playgroud)

更新:

第二种解决方案的替代方案:获取所有成员的函数指针并将它们保存到临时变量中:

template<typename T>
class A
{
    void foo() {...}
protected:
    void instantiate() { void (A::*p)() = &A::foo; }
};

template<typename T>
class B : public A<T>
{
    void bar() {...}
protected:
    void instantiate() { A<T>::instantiate(); void (B::*p)() = &B::foo; }
};
Run Code Online (Sandbox Code Playgroud)