Reputation: 1189
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
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
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
Reputation: 1057
I suggest boost:: any
. But really, does polymorphism not solve your problem?
Upvotes: 0