C++ 转换boost::variant类型的std::vector
如何实现下面的函数,将C++ 转换boost::variant类型的std::vector,c++,boost,c++98,C++,Boost,C++98,如何实现下面的函数,将值的向量转换为容器?如果值的所有成员不是同一类型,即如果向量包含字符串和整数的混合,我希望断言。这是因为函数的返回值是std::vector或std::vector typedef boost::变量值; typedef boost::variant容器; 容器值容器(常量标准::向量和值) { 返回容器(); } struct converter\u访问者:public boost::static\u访问者 { 常数std::向量&_cont; 转换器(const std
值的向量
转换为容器
?如果值
的所有成员不是同一类型,即如果向量包含字符串和整数的混合,我希望断言。这是因为函数的返回值是std::vector
或std::vector
typedef boost::变量值;
typedef boost::variant容器;
容器值容器(常量标准::向量和值)
{
返回容器();
}
struct converter\u访问者:public boost::static\u访问者
{
常数std::向量&_cont;
转换器(const std::vector&r):_cont(r){}
模板
容器运算符()(常量T&)常量{
std::向量ans;
ans.reserve(_cont.size());
对于(int i=0;i<_cont.size();++i)
推回(boost::get(_cont[i]);
返回ans;
}
};
容器值容器(常量标准::向量和值){
//假设!values.empty()
返回boost::apply_visitor(converter_visitor(values),values.front());
}
如果
值的所有元素不是同一类型的,这将抛出一个错误。\n这可能会派上用场,可能是:
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);
你在问什么。您想知道如何检查元素是否都是同一类型的吗?还是你在问如何进行转换?到目前为止你试过什么?您是否知道boost::apply_visitor
?
struct converter_visitor : public boost::static_visitor<Container>
{
const std::vector<Value> & _cont;
converter_visitor(const std::vector<Value> &r) : _cont(r) {}
template<class T>
Container operator()(const T &) const {
std::vector<T> ans;
ans.reserve(_cont.size());
for (int i=0;i < _cont.size();++i)
ans.push_back( boost::get<T>(_cont[i]));
return ans;
}
};
Container valuesToContainer(const std::vector<Value> & values) {
//assuming !values.empty()
return boost::apply_visitor( converter_visitor(values),values.front());
}
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);
#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,