简体   繁体   中英

C++ member template for boost ptr_vector

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 model {
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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM