Шаблон члена C ++ для повышения ptr_vector - PullRequest
1 голос
/ 28 мая 2010

Я пытаюсь написать контейнерный класс, используя boost :: ptr_vector. Внутри ptr_vector я бы хотел включить разные классы. Я пытаюсь добиться этого с помощью статических шаблонов, но пока я не могу этого сделать. Например, класс контейнера -

class model {
private:
  boost::ptr_vector<elem_type> elements;
public:
  void insert_element(elem_type *a) {
element_list.push_back(a);
  }
};

и я пытаюсь использовать разные классы elem_type. Код ниже не соответствует моим требованиям:

template <typename T>class model {
private:
  boost::ptr_vector<T> elements;
public:
  void insert_element(T *a) {
element_list.push_back(a);
  }
};

потому что, когда я инициализирую контейнерный класс, я могу использовать только один класс в качестве шаблона:

model <elem_type_1> model_thing;
model_thing.insert_element(new elem_type_1)

но не elem_type_2:

model_thing.insert_element(new elem_type_2)//error, of course

Можно сделать что-то вроде использования шаблонов только на элементе?

 class model {
private:
 template <typename T> boost::ptr_vector<T> elements;
public:
  void insert_element(T *a) {
element_list.push_back(a);
  }
}; //wrong

Так я могу вызвать insert_element для определенного класса, который я хочу вставить? Обратите внимание, что я не хочу использовать виртуальные члены. Спасибо!

Ответы [ 2 ]

1 голос
/ 30 мая 2010

Попробуйте использовать вектор boost :: variable :

#include <iostream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>

struct Foo
{
    Foo(int v=0) : a(v) {}
    int a;
};

struct Bar
{
    Bar(int v=0) : b(v) {}
    int b;
};

struct print_visitor : public boost::static_visitor<>
{
    void operator()(const Foo& foo) const
    {
        std::cout << "Foo " << foo.a << "\n";
    }

    void operator()(const Bar& bar) const
    {
        std::cout << "Bar " << bar.b << "\n";
    }
};

int main()
{
    typedef boost::variant<Foo, Bar> Variant;
    std::vector<Variant> bag;
    bag.push_back(Foo(123));
    bag.push_back(Bar(456));

    BOOST_FOREACH(const Variant& element, bag)
    {
        boost::apply_visitor(print_visitor(), element);
    }
}

Boost :: варианта apply_visitor функции полезны для предотвращения чрезмерного приведения обратно к исходному типу.

0 голосов
/ 28 мая 2010

Вектор содержит элементы, каждый из которых имеет тот же тип, что и другие. Если вы хотите создать вектор элементов разных классов, вы можете использовать вектор элементов типа boost::any.

...