转换boost::变体类型的std::vector
Convert a std::vector of a boost::variant type
我如何实现下面的函数从Value
的向量转换为Container
?我想断言values
的所有成员是否都是同一类型,即如果向量包含字符串和int的混合。这是因为函数的返回值要么是std::vector<int>
,要么是std::vector<std::string>
。
typedef boost::variant<int, std::string> Value;
typedef boost::variant<std::vector<int>, std::vector<std::string> > Container;
Container valuesToContainer(const std::vector<Value>& values)
{
return Container();
}
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());
}
如果不是所有的values
元素都是同一类型,将抛出bad_get
这可能会派上用场:
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请求的函数的不同之处在于,当不是所有元素类型都同意时,它将返回一个元组向量("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,
相关文章:
- 如何获取std::result_of函数的返回类型
- 如何在c++迭代器类型中包装std::chrono
- 在C++中对T*类型执行std::move的意外行为
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在一个模板函数中,若输入的类型是enum类,我该如何使用std::underlying_type
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- std::visit无法识别类型
- 哪些类型可以转换为std::any
- 从类型std::函数传递变量失败,尽管调用方期望的类型完全相同
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- r语言 - C++ 类型为"const std ::?
- C++中"std::sort"比较器的不同类型
- C++11 中不同类型的对象的 std::array 的替代方案
- 检查某些类型是否是模板类 std::optional 的实例化
- clion 无法解析 std 类型
- 使用 std 类型的 ADL 无法找到运算符
- 为什么 std 类型不提供来自分配器不同源的转换构造函数/赋值
- 哪些 std 类型在移动构造函数中用作 arg 后保证为空/空
- Qt -混合Qt和std:: c++类型