Это может пригодиться, может быть:
template <typename... T> using VariantVector = std::vector<boost::variant<T...>>;
template <typename... T> using VectorPack = std::tuple<std::vector<T>...>;
template <typename... T>
VectorPack<T...> splitVectors(VariantVector<T...> const &values);
Разница с функцией запрошенной OP является то, что вместо «erroring», когда не все типы элементов согласен, он будет возвращать кортеж из векторы («VectorPack»), и вы можете просто выбрать, какой из них вы хотите.
Демо-программа:
#include <boost/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <tuple>
#include <vector>
using std::get;
template <typename... T> using VariantVector = std::vector<boost::variant<T...>>;
template <typename... T> using VectorPack = std::tuple<std::vector<T>...>;
namespace detail
{
template <typename T>
struct VectorSplitterMixin {
void operator()(T const& v) { _bucket.push_back(v); }
std::vector<T> _bucket;
};
template <typename... T>
struct VectorSplitter : boost::static_visitor<>, VectorSplitterMixin<T>...
{
typedef VectorPack<T...> product_t;
product_t product() {
return product_t { std::move(static_cast<VectorSplitterMixin<T>*>(this)->_bucket)... };
}
};
}
template <typename T> struct X;
template <typename... T>
VectorPack<T...> splitVectors(VariantVector<T...> const &values)
{
auto splitter = detail::VectorSplitter<T...>();
for (auto& val : values)
boost::apply_visitor(splitter, val);
return splitter.product();
}
int main()
{
typedef boost::variant<int, std::string> Value;
typedef boost::variant<std::vector<int>, std::vector<std::string> > Container;
const std::vector<Value> vec { 42, "hello world", 1, -99, "more" };
auto vectorPack = splitVectors<int, std::string>(vec);
for (auto i : get<0>(vectorPack))
std::cout << "int:" << i << ", ";
std::cout << "\n";
for (auto& s : get<1>(vectorPack))
std::cout << "string:" << s << ", ";
std::cout << "\n";
}
Печать:
int:42, int:1, int:-99,
string:hello world, string:more,
Что вы спрашиваете. Вы хотите знать, как вы можете проверить, все ли элементы одного типа? Или вы спрашиваете, как сделать конверсию? что ты уже испробовал? Вы знаете о «boost :: apply_visitor»? – sellibitze