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)
但这不编译.还有其他方法可以实现这一目标吗?
也许不优雅但至少可行:提供一个宏来实例化模板并要求用户使用该宏而不是手动实例化:
// 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)
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |