C++ 如何显式实例化基模板类?
这个问题考虑的是模板类的显式实例化 考虑从另一个模板类C++ 如何显式实例化基模板类?,c++,templates,inheritance,explicit-instantiation,C++,Templates,Inheritance,Explicit Instantiation,这个问题考虑的是模板类的显式实例化 考虑从另一个模板类a派生的模板类B。我想显式实例化B,因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的。当然,还将调用从A继承的方法,因此它们也必须实例化 看起来,C++在显式地设置模板类时不会初始化基类,正如在这个问题中所提出的: 例如: 模板 类{void foo(){…}}; 模板 B类:公共A{} 模板类别B;//这不会实例化A::foo()!!! 当然,我还需要实例化所有基类。但是,我不想给客户机代码带来负担,
a
派生的模板类B
。我想显式实例化B
,因为它的方法是从动态链接调用的,所以这些方法必须实例化,尽管它们不是在代码本身中调用的。当然,还将调用从A
继承的方法,因此它们也必须实例化
<>看起来,C++在显式地设置模板类时不会初始化基类,正如在这个问题中所提出的:
例如:
模板
类{void foo(){…}};
模板
B类:公共A{}
模板类别B;//这不会实例化A::foo()!!!
当然,我还需要实例化所有基类。但是,我不想给客户机代码带来负担,因为类的层次结构可能很深。考虑包含10个或更多模板类的类层次结构。不应敦促客户机编写10个显式模板实例。这不仅仅是大量的写作;当我对类层次结构进行更改时,它也会中断
相反,我希望以某种方式实现,无论何时实例化B
,它的所有基类都是如此。我尝试简单地在B中实例化基类,如下所示:
template<typename T>
class B : public A<T> {
template class A<T>; // Does not compile!
}
模板
B类:公共A{
模板类A;//未编译!
}
但这并不适用于编译。是否有其他方法可以实现这一点?可能不优雅,但至少可行:提供一个宏来实例化模板,并要求用户使用宏来代替手动实例化:
// 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>;
更新:
第二种解决方案的替代方案:获取所有成员的函数指针并将其保存到临时变量:
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; }
};
模板
甲级
{
void foo(){…}
受保护的:
void实例化(){void(A::*p)(=&A::foo;}
};
模板
B类:公共A
{
无效条(){…}
受保护的:
void instantiate(){A::instantiate();void(B::*p)(=&B::foo;}
};
第二种解决方案的问题是,某些方法具有较大的签名,并且不容易生成值以提供给这些方法。第一种方法可以工作,但确实很难看:(.添加了第二种解决方案的变体,尽管这几乎是冗长的,并且不是真正需要的:其思想是instantiate()
从未真正执行过。好吧,这更可行。但是,接口仍然很大,所以枚举所有方法比枚举所有基类要困难得多。我希望有其他方法可以解决这个问题,不过还是要感谢您的回答。
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; }
};