我有一个模板类C_Foo
struct Bar_Base { ... }; struct Bar_1 : public Bar_Base { ... }; struct Bar_2 : public Bar_Base { ... }; struct Bar_3 : public Bar_Base { ... }; class C_Foo{ ... }; class C_Foo_1 : public C_Foo { ... }; class C_Foo_2 : public C_Foo { ... }; class C_Foo_3 : public C_Foo { ... };
实例化如下:
C_Foo_1 foo1; C_Foo_2 foo2; C_Foo_3 foo3;
我有一组常见的操作,所有操作都是在C_Foo上定义的,我想在foo1,foo2和foo3上执行.我尝试过以下方法:
vectorv; v.push_back(&foo1); v.push_back(&foo2); v.push_back(&foo3);
但是我得到编译错误,大概是因为编译器不确定如何从C_Foo_1转到C_Foo.
可以这样做吗?我希望能够循环遍历foo1 ... fooN并对所有这些操作执行相同的操作,而不必像这样复制和粘贴样板代码:
foo1.do_stuff(); foo2.do_stuff(); foo3.do_stuff();
谢谢你的帮助.
如果函数不依赖于模板参数,则可以这样做:
// note: not a template class C_Foo_Common { public: virtual void do_stuff() = 0; }; templateclass C_Foo : public C_Foo_Common { virtual void do_stuff() { // do stuff... } }; vector v; v.push_back(&foo1); v.push_back(&foo2); v.push_back(&foo3); // now, you can iterate and call do_stuff on them.
但是如果C_Foo_Common中的函数需要知道类型T
(例如,要有另一个依赖于T的返回类型),那就不可能了.C_Foo
是一种不同的类型C_Foo
.您可以使用受歧视的联盟.那些跟踪存储在它们中的内容并且完全是通用的:
typedef boost::variant< C_Foo*, C_Foo *, C_Foo * > variant_type; vector v; v.push_back(&foo1); v.push_back(&foo2); v.push_back(&foo3);
变体知道它存储的内容,并且可以调用函数重载可以存储在其中的类型.阅读文档boost::variant
以获取有关如何获取变体包含的内容的更多信息.