2015-04-01 2 views
-4

У меня есть шаблонный класс (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();

Конечно, это не работает, потому что я не обеспечивают аргумент шаблона во время конвертирования .... Но, я не нахожу хороший способ сделать это.

У вас есть идея?

+2

Пожалуйста, пост некоторый реальный код. 'A <1> a0();' - объявление функции. – juanchopanza

+0

Это настоящий код. 'A <1> a0();' вызывает конструктор. Удалите нижний план. – Oli

+0

Нет. Это объявление функции. См. * Самый неприятный синтаксический анализ *. – Bathsheba

ответ

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! 
+0

Это прекрасно работает. Спасибо. – Oli

+0

@Oli: Если это основное использование вашего класса, вы, вероятно, захотите снова проверить свою производительность. Введение базового класса для доступа к вашим классам (политиками) может привести к увеличению производительности, создаваемому тем, что вы планируете этот класс в первую очередь. – MikeMB

Смежные вопросы