如何模拟方法模板的虚拟性
我有一个类层次结构,我想在其中引入一个方法模板,其行为就像虚拟的一样。例如一个简单的层次结构:
class A {
virtual ~A() {}
template<typename T>
void method(T &t) {}
};
class B : public A {
template<typename T>
void method(T &t) {}
};
然后我创建对象 B:
A *a = new B();
我知道我可以通过 typeid(a)
获取存储在 a
中的类型。当我知道类型时,如何动态调用正确的 B::method
?我可能会遇到这样的情况:
if(typeid(*a)==typeid(B))
static_cast<B*>(a)->method(params);
但我想避免出现这样的情况。我正在考虑创建一个以 typeid
作为键的 std::map
,但是我会放什么作为值呢?
I have a class hierarchy where I want to introduce a method template that would behave like if it was virtual. For example a simple hierarchy:
class A {
virtual ~A() {}
template<typename T>
void method(T &t) {}
};
class B : public A {
template<typename T>
void method(T &t) {}
};
Then I create object B:
A *a = new B();
I know I can get the type stored in a
by typeid(a)
. How can I call the correct B::method
dynamically when I know the type? I could probably have a condition like:
if(typeid(*a)==typeid(B))
static_cast<B*>(a)->method(params);
But I would like to avoid having conditions like that. I was thinking about creating a std::map
with typeid
as a key, but what would I put as a value?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以使用“奇怪的重复模板模式”
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
使用此模式,基类采用派生类类型作为模板参数,这意味着基类可以将自身转换为派生类型,以便调用派生类中的函数。它是一种虚拟函数的编译时实现,具有不必执行虚拟函数调用的额外好处。
然后就可以像这样使用...
You can use the "Curiously Recurring Template Pattern"
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Using this pattern, the base class takes the derived class type as a template parameter, meaning that the base class can cast itself to the derived type in order to call functions in the derived class. It's a sort of compile time implementation of virtual functions, with the added benefit of not having to do a virtual function call.
It can then be used like this...
有没有可以提取并虚拟化的通用代码?
Is there any common code you could extract and make virtual?
您可能知道,您不能拥有虚函数的模板,因为整个虚函数都是类类型的一部分,并且必须提前知道。这排除了任何简单的“任意覆盖”。
如果可以的话,您可以将模板参数作为类的一部分:
更复杂的方法可能会使用一些调度程序对象:
As you may know, you cannot have templates for virtual functions, since the entirety of the virtual functions is part of the class type and must be known in advance. That rules out any simple "arbitrary overriding".
If it's an option, you could make the template parameter part of the class:
A more involved approach might use some dispatcher object:
哎呀。最初回答错误的问题 - 啊好吧,在另一个问题
经过一番思考,我认为这是经典的多方法要求,即基于多个参数的运行时类型。相比之下,通常的虚拟函数是
单一调度
(它们仅在this
类型上调度)。请参阅以下内容:
维基百科有一个很好的简单的文章和示例关于 C++ 中的多重调度。
以下是维基百科文章中的“简单”方法供参考(不太简单的方法对于大量派生类型的扩展效果更好):
Oops. Initially answered at the wrong question - ah well, at another question
After some thinking I recognized this as the classic multi-method requirement, i.e. a method that dispatches based on the runtime type of more than one parameter. Usual virtual functions are
single dispatch
in comparison (and they dispatch on the type ofthis
only).Refer to the following:
Wikipedia has quite a nice simple write-up with examples on Multiple Dispatch in C++.
Here is the 'simple' approach from the wikipedia article for reference (the less simple approach scales better for larger number of derived types):
我认为唯一的解决方案是 http://en.wikipedia.org/wiki/Visitor_pattern
请参阅此主题:
如何用C++实现“虚拟模板功能”
I think the only solution is the http://en.wikipedia.org/wiki/Visitor_pattern
See this topic:
How to achieve "virtual template function" in C++