如何显式实例化基本模板类?

时间:2014-05-19 13:58:13

标签: c++ templates inheritance explicit-instantiation

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

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

似乎C ++在显式实例化模板类时不会实例化基类,如本问题所述: Do Explicit Instantiations of C++ Class Templates Instantiate Dependent Base Classes? 例如:

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()!!!

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

相反,我希望以某种方式实现每当B<T>实例化时,它的所有基类都是如此。我尝试简单地在B本身中实现基类,如下所示:

template<typename T>
class B : public A<T> {
    template class A<T>; // Does not compile!
}

但是这不能编译。还有其他方法可以实现这个目标吗?

1 个答案:

答案 0 :(得分: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>;

如果您愿意&#34;污染&#34;用于强制使用实例化宏的类接口:添加一个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

<强>更新

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

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; }
};