我有一个模板方法,使用boost :: get of boost:variant模块:
typedef boost::variant<int, std::string, bool, uint8_t> Variant;
template <class T>
void write(const Variant& t) {
size_t sizeT = boost::apply_visitor(SizeOfVisitor(), t);
memcpy(&v[offset], &boost::get<T>(t), sizeT);
}
问题是我只在运行时才知道Variant的基础类型。而且AFAIK我只能使用which()
method进行查询。
有什么方法可以传递类型T,它是此方法的基本Variant类型?例如,使用which()
我不知道的类型是什么,但是如何传递呢?
switch (m_var.which()) { // Returns an int index of types in the order of passed template classes
case 0: // This is int
case 1: // This is std::string
...
}
...
Writer.write<???>(m_var); // How to pass the type here?
编辑:如果您知道任何其他方式来获得所需的结果-实际获取boost :: variant内部变量的地址,要从那里复制,请与我分享您的想法
谢谢
我碰巧在这里写了一个非常相似的答案:
同样,最重要的是与非POD数据类型一起使用完全是伪造的memcpy
(因此您不能与std::string
.ever一起使用)。
variant
使用仅在运行时已知的类型对进行操作的方法是使用boost::static_visitor<>
。
这是经过main()
改编的示例,很接近您想要实现的目标,显然,
#include <boost/variant.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp> // just as a sample
#include <iostream>
namespace serialization {
namespace customization {
template<typename T, typename Out, typename R = typename boost::enable_if<boost::is_pod<T>, void>::type>
void do_serialize(T const& x, Out& out)
{
static_assert(boost::is_pod<T>(), "");
char const* rawp = reinterpret_cast<char const*>(&x);
std::copy(rawp, rawp+sizeof(T), out);
}
template<typename Out>
void do_serialize(std::string const& x, Out& out)
{
do_serialize(x.size(), out);
for(auto ch : x)
do_serialize(ch, out);
}
}
struct serialize_f : public boost::static_visitor<> {
template<typename Out, typename... T>
void operator()(boost::variant<T...> const& v, Out& out) const
{
boost::apply_visitor(boost::bind(*this, _1, boost::ref(out)), v);
}
template<typename T, typename Out>
void operator()(T const& x, Out& out) const
{
using customization::do_serialize; // ADL dispatch
do_serialize(x, out);
}
};
template <typename T, typename Out>
Out serialize(T const& v, Out out) {
const static serialize_f _vis {};
_vis(v, out);
return out;
}
}
namespace MyUserTypes {
struct A {
std::string name;
int i;
};
template<typename Out> void do_serialize(A const& v, Out& out) { // ADL will find this
serialization::serialize(v.name, out);
serialization::serialize(v.i, out);
}
}
int main() {
using namespace serialization;
std::vector<uint8_t> binary_data;
auto out_inserter = back_inserter(binary_data);
// variants and custom types
typedef boost::variant<MyUserTypes::A, boost::array<char, 42> > V;
MyUserTypes::A myA { "0123456789", 99 };
V v = boost::array<char,42>();
serialize(myA, out_inserter);
serialize(v, out_inserter);
v = myA;
serialize(v, out_inserter);
std::cout << "Bytes in binary_data vector: " << binary_data.size() << "\n";
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句