Вы можете использовать boost::any
. Например:
#include <vector>
#include <boost/any.hpp>
#include <iostream>
struct my_class { my_class(int i) : x{i} { } int x; };
int main()
{
std::vector<boost::any> v;
v.push_back(42);
v.push_back(std::string{"Hello!"});
v.push_back(my_class{1729});
my_class obj = boost::any_cast<my_class>(v[2]);
std::cout << obj.x;
}
Если вы хотите ограничить набор допустимых типов в какой-то определенный диапазон, вы можете использовать вместо boost::variant
:
#include <vector>
#include <boost/variant.hpp>
#include <iostream>
struct my_class { my_class(int i) : x{i} { } int x; };
int main()
{
typedef boost::variant<int, std::string, my_class> my_variant;
std::vector<my_variant> v;
v.push_back(42);
v.push_back("Hello!");
v.push_back(my_class{1729});
my_class obj = boost::get<my_class>(v[2]);
std::cout << obj.x;
}
boost::variant
также поддерживает посещения. Вы можете определить посетителя, который может обрабатывать все возможные типы в варианте:
struct my_visitor : boost::static_visitor<void>
{
void operator() (int i)
{
std::cout << "Look, I got an int! " << i << std::endl;
}
void operator() (std::string const& s)
{
std::cout << "Look, I got an string! " << s << std::endl;
}
void operator() (my_class const& obj)
{
std::cout << "Look, I got a UDT! And inside it a " << obj.x << std::endl;
}
};
И затем вызвать его, как это сделано ниже:
int main()
{
typedef boost::variant<int, std::string, my_class> my_variant;
std::vector<my_variant> v;
v.push_back(42);
v.push_back("Hello!");
v.push_back(my_class{1729});
my_visitor mv;
for (auto const& e : v)
{
e.apply_visitor(mv);
}
}
Вот live example. Хорошая вещь о boost::variant
заключается в том, что она выполнит проверку времени компиляции, чтобы убедиться, что ваш посетитель может обрабатывать все типы, которые может содержать этот вариант.
Возможно, есть вектор «boost :: variant». – chris
Другим выбором является 'boost :: any' – dchhetri
не' std :: vector', а 'std :: tuple' (в C++ 11). std :: vector - контейнер однородных типов. –