在下面的示例中,我假设类模板函数get_count()
将有两个不同的实例化,这是多余的,因为它们不依赖于模板参数。这是真的(还是优化了?(,当涉及到某些成员函数时,有没有办法使模板的所有实例化都使用通用函数(也许是一些模板参数通配符,如<*>
?
template<class T>
class A {
private:
T obj;
int count;
public:
int get_count();
};
template<class T>
int A<T>::get_count() { // This function doesn't really need to
// depend on the template parameter.
return this->count;
}
int main() {
A<int> a; //<--First template instantiation
A<bool> b; //<--Second template instantiation
int i = a.get_count(); //<--Could theoretically use the same code
int j = b.get_count(); //<--
return 0;
}
另外,如果成员变量被重新排列怎么办?
错特错地假设所有实例化都可以使用相同的代码进行A<..>::get_count()
。
看看班级成员:
T obj;
int count;
因此,tamplate参数T
决定了count
的偏移量,即返回的成员get_count()
。
无论如何,如果两个实例化碰巧产生相同的指令,没有什么会阻止编译器合并它们。
作为 QoI 问题,如果启用了优化,则应该这样做。
有一种方法可以使多个类对函数使用相同的代码,而无需依赖编译器优化:
派生自提供该功能的公共基础。
struct A_base {
int get_count();
protected:
int count;
}
template<class T>
class A : A_base {
T obj;
};
int A_base::get_count() {
return this->count;
}
(尽管如此,最终,假设规则仍然至高无上:编译器可能会复制代码以公开优化可能性,否则无法使用。
是的,有一种方法,它是一种使用的实现技术:
创建一个不依赖于模板参数的基类,并将与模板无关的代码放在那里。这将仅进行一次实例化。对于模板参数依赖代码,请在模板类本身中执行此操作:
class base {
int count;
public:
std::size_t get_count()...
};
template <class T>
class derived : public base {};
类似的技术用于减少实现中的代码膨胀。