这个问题正在考虑模板类的明确实例化。
考虑从另一个模板类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!
}
但是这不能编译。还有其他方法可以实现这个目标吗?
答案 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; }
};