用template函数设计层次类

Designing hiearchical classes with template function

本文关键字:层次 template 函数      更新时间:2023-10-16

我正在编写一个类Base,它有一个采用模板参数的成员函数:

class Base {
  template<class T>
  void func(const T& t) { ... }
};

有一个类Derived在概念上继承了Base的性质,并具有相同的函数func,但实现方式不同。

起初我想从Base派生Derived,并使func虚拟化,但我不能,因为它是模板。

我也想过CRTP,但这是一个选项,因为实例必须能够放入容器中,并且可以在不知道它们的确切类型的情况下访问:

std::vector<Base*> v = ...;
v[0]->func(...);
v[1]->func(...);

可能类型的T也不能过载。

解决这种情况的最佳方案是什么?

除了这个话题,你会推荐这类问题的参考资料(最好是书籍(吗?

不能像那样混合编译时多态性(模板(和运行时多态性。问题是,使用模板时,编译器将按需生成代码,在您的特定情况下,您需要根据向量中对象的运行时类型来决定实例化哪个成员函数。

如果可以与方法一起使用的类型数量有限,您可以提供不同的虚拟重载,如果您不想手动这样做,您可能可以定义一个包含所有类型t的类型列表,然后使用该类型列表生成方法。。。但这将是可怕的编码和维护。

我建议您说明问题的实际要求(而不是您提出的解决方案的要求(,人们将能够提供替代方法。

这不是用C++容易做到的。它与所谓的"第一类多态性"有关,这意味着如果C++中的值可以具有多态类型,那就很容易了。事实并非如此。

如果您可以使用通用解决方案(这意味着所有T的代码f必须相同(,您也许可以这样做,但这将是一项艰巨的任务。

基本上,您需要将const T &t参数替换为一个参数,该参数的类型不是泛型的,但将从所有可能类型的t中"内部"捕获f所需的所有行为。

举个例子,假设T是一个函子,fint参数调用它。在这种情况下,您将把声明更改为

  virtual void func(const std::function<void(int)>& t) { ... }

虚拟功能将开始工作。然而,这意味着在开始在派生类中实现T之前,必须修复它的接口(这意味着,如果您改变主意,想用类型为ostream的参数调用t,那就太倒霉了(。

然而,创建这样的多态包装器从简单(如boost::anyboost::function(到困难甚至不可能(any_iterator(。这在很大程度上取决于你想做什么。