我有一个模板化的类(BTW,我使用模板化的类,因为它可以带来巨大的性能提升):
template<int n>
class A;
我的第一个问题是我想制作它的载体。有人建议使用boost::any
,现在我只使用void*
。
A<1> a0;
A<2> a1;
vector<void*> v;
v.push_back(&a0);
v.push_back(&a1);
当我想调用此向量元素的某个成员函数时,问题出现了:
for(auto a : v)
(A*)a->foo();
当然,这不起作用,因为我在转换过程中没有提供模板参数.... 但是,我找不到任何有效的方法来实现这一目标。
你有什么想法吗?
答案 0 :(得分:3)
A<1>
和A<2>
是完全独立的类。
考虑一下:如果你有两个类X和Y都有foo
方法:
class X {public: void foo() {std::cout << "X::foo" << std::endl;}};
class Y {public: void foo() {std::cout << "Y::foo" << std::endl;}};
以及void*
的向量,那么如何在所有这些方法上调用foo
方法?
vector<void*> v;
v.push_back(new X);
v.push_back(new Y);
for(auto a : v)
a->foo(); // how can I do this?
答案很简单:你不能按名称
来访问会员。(如果某人创建的课程Z
也有foo
方法怎么办?如果向量中有Z
,您会希望调用它;但是成员编译代码时删除名称,因此不知道该成员也被称为foo
!)
但是,您可以创建基类并使方法成为虚拟:
class XYBase {
public:
virtual void foo() = 0;
}
class X : public XYBase {public: void foo() {std::cout << "X::foo" << std::endl;}};
class Y : public XYBase {public: void foo() {std::cout << "Y::foo" << std::endl;}};
然后你可以拥有vector<XYBase*>
:
vector<XYBase*> v;
v.push_back(new X);
v.push_back(new Y);
for(auto a : v)
a->foo(); // works!
等效的模板将是:
class XBase {
public:
virtual void foo() = 0;
}
template<int N> class X : public XBase {
public:
void foo() {
std::cout << "X<" << N << ">::foo" << std::endl;
}
};
// ... later ...
vector<XBase*> v;
v.push_back(new X<1>);
v.push_back(new X<2>);
for(auto a : v)
a->foo(); // works!