【问题标题】:call member function of a vector of templated class调用模板类向量的成员函数
【发布时间】:2015-04-01 07:55:00
【问题描述】:

我有一个模板类(顺便说一句,我使用模板类,因为它可以带来巨大的性能提升):

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();

当然,这不起作用,因为我在转换过程中没有提供模板参数.... 但是,我没有找到任何好的方法来实现这一点。

你有什么想法吗?

【问题讨论】:

  • 请贴一些真实的代码。 A&lt;1&gt; a0(); 是一个函数声明。
  • 这是真实的代码。 A&lt;1&gt; a0(); 调用构造函数。删除您的反对票。
  • 没有。这是一个函数声明。请参阅最令人头疼的解析
  • A&lt;1&gt; a0;A&lt;1&gt; a0{};调用构造函数,A&lt;1&gt; a0();是函数声明。
  • 好吧,你是对的。但是,堆栈溢出什么时候变得如此卑鄙了?根据维基百科,这是一个非常微妙的错误。我刚刚发布了我的实际代码的简化版本,其中包含构造函数参数。

标签: c++ templates vector


【解决方案1】:

A&lt;1&gt;A&lt;2&gt;完全独立的类

考虑:如果您有两个类 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&lt;XYBase*&gt;:

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!

【讨论】:

  • @Oli:如果这是您的课程的主要用途,您可能想再次检查您的表现。引入基类以便以多态方式访问您的类可能会消耗您首先通过模板化该类而获得的任何性能提升。
猜你喜欢
  • 2010-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多