prgbenz
prgbenz

Reputation: 1189

how to customize a c++ list container such that it can hold different types of structs?

how to customise a c++ list container such that it can holds different type of struct ?

for example

struct A
{
  int a;
  int b;
}

struct B
{
  float a;
  float b;
}


#include <list>
using namespace std;
int main()
{
   ...
   ...
   A a;
   a.a = 1;
   a.b = 2;

   B b;
   b.a = 123.444;
   b.b = 11.222;

   List.push_back(a);
   List.push_back(b);

   return 0;
}

Upvotes: 0

Views: 109

Answers (3)

nosid
nosid

Reputation: 50154

In some cases it makes sense to store different types in a container. C++ supports these use cases with unions, but this feature is very basic. I recommend using boost::variant instead of unions if you really need to store different types in a container. I also recommend using std::vector instead of std::list, because otherwise it doesn't make much sense to use this optimization.

Here is an example with boost::variant:

std::vector<boost::variant<A, B>> items;
A a = ...;
B b = ...;
items.push_back(a);
items.push_back(b);
struct get_length : boost::static_visitor<double>
{
    double operator()(const A& f) const { return calc(f.a, f.b); }
    double operator()(const B& b) const { return calc(b.a, b.b); }
    double calc(double a, double b) const { return std::sqrt(a * a + b * b); }
};
for (auto&& item : items) {
    double d = boost::apply_visitor(get_length(), item);
    std::cout << d << '\n';
}

Upvotes: 1

Ed Barbu
Ed Barbu

Reputation: 1649

Why not polymorphism and a list of pointers to the objects? Be careful about object lifetime. The pointers in the list will become invalid once the two objects go out of scope. You can alternatively dynamically allocate (new) the two elements and delete them when you're done, then remove them from the list.

Later edit: I get the feeling you are new to C++. After studying dynamic allocation, I recommend you look up smart pointers. They lift the burden of manually managing memory by doing it themselves:

unique_ptr and shared_ptr

You can use them inside the list instead of naked pointers.

struct Base
{
    virtual ~Base(){}
};
struct A : public Base
{
  int a;
  int b;
};

struct B : public Base
{
  float a;
  float b;
};


#include <list>
using namespace std;
int main()
{
   ...
   ...
   A a;
   a.a = 1;
   a.b = 2;

   B b;
   b.a = 123.444;
   b.b = 11.222;

   std::list<Base*> l;
   l.push_back(&a);
   l.push_back(&b);

   return 0;
}

Upvotes: 1

smiling_nameless
smiling_nameless

Reputation: 1057

I suggest boost:: any. But really, does polymorphism not solve your problem?

Upvotes: 0

Related Questions