【问题标题】:Designing hiearchical classes with template function使用模板函数设计层次类
【发布时间】:2011-11-30 16:43:21
【问题描述】:

我正在编写一个类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 的可能类型也不是一种选择。

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

除了主题之外,您会推荐此类问题的参考资料(最好是书籍)吗?

【问题讨论】:

  • 你能把整个Base 做成一个模板吗?制作func 然后是虚拟的不会有问题。
  • @eran:这会极大地改变语义,目前单个对象可以作为 func 成员函数的参数传递给多个类型,如果应用了您提出的更改,您将不得不生成一组单独的对象,每个对象将处理一个类型作为 func 的参数

标签: c++ templates polymorphism


【解决方案1】:

您不能像这样将编译时多态性(模板)与运行时多态性混合在一起。问题是使用模板时,编译器会在使用时生成代码on-demand,在您的特定情况下,您希望根据运行时类型决定要实例化的成员函数向量中的对象。

如果可以与方法一起使用的类型数量有限,您可以提供不同的虚拟重载,如果您不想手动执行此操作,您可以定义一个包含所有类型 T 的类型列表,然后使用该类型列表来生成方法……但这对于编码和维护来说会很糟糕。

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

【讨论】:

    【解决方案2】:

    这不是用 C++ 轻松完成的。它与称为“第一类多态性”的东西有关,这意味着如果 C++ 中的值可以具有多态类型,那将很容易。事实并非如此。

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

    基本上,您需要将 const T &amp;t 参数替换为类型不是通用的参数,但会“内部”捕获 f 需要的所有可能类型的 ts 的所有行为.

    例如,假设T 是一个函子,f 使用int 参数调用。在这种情况下,您需要将声明更改为

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

    虚拟功能将开始工作。但是,这意味着必须先修复Ts 的接口,然后才能开始在派生类中实现它(这意味着如果您改变主意并希望使用ostream 类型的参数调用t,您'运气不好)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2016-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-26
      • 2013-11-21
      相关资源
      最近更新 更多