我正在编写一个类Base
,它有一个成员函数,它带有一个模板参数:
class Base {
template<class T>
void func(const T& t) { ... }
};
有一个类Derived
,它在概念上继承了Base
的性质,并具有相同的函数func
,具有不同的实现。
起初我想过从Derived
派生Base
并让func
虚拟,但我不能,因为它是模板。
我也想过CRTP,但它是一个选项,因为实例必须能够放入容器并且可以在不知道其确切类型的情况下访问:
std::vector<Base*> v = ...;
v[0]->func(...);
v[1]->func(...);
对于T
的可能类型的重载也不是一种选择。
这种情况的最佳解决方案是什么?
除了这个话题,你会推荐这类问题的参考书(最好是书籍)吗?
答案 0 :(得分:1)
使用C ++并不容易。它与称为“第一类多态”的东西有关,这意味着如果C ++中的值可以具有多态类型,那将很容易。事实并非如此。
如果您对通用解决方案没问题(这意味着代码f
对于所有T
必须相同),您可以这样做,但这将是一项艰巨的任务。
基本上,您需要将const T &t
参数替换为类型不通用的参数,但会从{{1}中捕获“内部”所有行为f
的需求所有可能的类型。
举个例子,假设t
是一个仿函数,T
调用f
参数。在这种情况下,您将声明更改为
int
虚拟功能将开始工作。但是,这意味着在开始在派生类中实现 virtual void func(const std::function<void(int)>& t) { ... }
之前必须修复T
s的接口(这意味着如果你改变主意并希望使用{{1}类型的参数调用t
1}},你运气不好。
但是,创建这样的多态包装器的范围从简单(如boost::any
,boost::function
)到硬甚至不可能(any_iterator
)。这非常依赖于你想做的事情。
答案 1 :(得分:0)
您不能将编译时多态(模板)与运行时多态性混合在一起。问题是,使用模板时,编译器将在使用时生成代码 on-demand ,在您的特定情况下,您希望根据运行时类型确定要实例化的成员函数。向量中的对象。
如果可以与方法一起使用的类型数量有限,则可以提供不同的虚拟重载,如果您不想手动执行,可以定义一个包含所有类型T的类型列表,然后使用该类型列表生成方法......但这对代码和维护来说会很糟糕。
我建议您说明问题的实际要求(而不是您提出的解决方案的要求),并且人们将能够提供替代方法。