开发者

C++ member template for boost ptr_vector

开发者 https://www.devze.com 2023-01-01 04:54 出处:网络
I\'m trying to write a container class using boost::ptr_vector. Inside the ptr_vector I would like to include different classes. I\'m trying to achieve that using static templates, but so far I\'m not

I'm trying to write a container class using boost::ptr_vector. Inside the ptr_vector I would like to include different classes. I'm trying to achieve that using static templates, but so far I'm not able to do that. For example, the container class is

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

and what I'm trying to achieve is be able to use different elem_type classes. The code below doesn't satisfy my requirements:

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

because when I initialize the container class I can only use one class as template:

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

but not elem_type_2:

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

It is possible to do something like using templates only on the member?

 class m开发者_如何学运维odel {
private:
 template <typename T> boost::ptr_vector<T> elements;
public:
  void insert_element(T *a) {
element_list.push_back(a);
  }
}; //wrong

So I can call the insert_element on the specific class that I want to insert? Note that I do not want to use virtual members. Thanks!


Try using a vector of boost::variant:

#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::variant's apply_visitor functions are useful for avoiding excessive casting back to the original type.


Vector is contains elements where each element has the same type as others. If you want to create vector of elements of different classes you could use vector of elements of type boost::any.

0

精彩评论

暂无评论...
验证码 换一张
取 消