如何通过类模板参数来提高::变种? [英] How to pass class template argument to boost::variant?

查看:106
本文介绍了如何通过类模板参数来提高::变种?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用的boost ::提振得到一个模板方法:变量模块:

I have a template method that uses boost::get of boost:variant module:

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类型。而且据我所知,我只能用其中()方法。

有什么办法,我可以通过T类型,这是这种方法的基本类型变异的?
例如,使用其中()我知道,什么类型的有,但如何通过它?

Is there any way I can pass the type T, which is the underlying type of Variant to this method? For instance, using which() I do know, what type there is, but how to pass it?

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 ::变种内变量的地址,从那里复制,请与我分享你的想法

If you know any other way to achieve the desired result - actually getting the address of boost::variant inner variable, to copy from there, please share with me your ideas

感谢您

推荐答案

我碰巧在这里写了一个非常类似的答案:

I happen to have written a very similar answer here:


  • <一个href=\"http://stackoverflow.com/questions/27012488/c-extract-size-of-boostvariant-element/27013615#27013615\">C++:升压变型元素的提取物::大小

此外,最重要的是,它的完全虚假使用的memcpy 与非POD数据类型(所以你的不能的std ::字符串使用它。永远)。

Again, the most important would be that it's completely bogus to use memcpy with non-POD datatypes (so you cannot use it with std::string. Ever).

变种运营方式 s的只在运行时已知类型是使用的boost :: static_visitor&LT;&GT;

The way to operate on variants with the type known only at runtime is using boost::static_visitor<>.

下面是用的例子中的main()适于靠近你想达到什么,显然,

Here's the example with main() adapted to be close to what you wanted to achieve, apparently,

<大骨节病> 住在Coliru

#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";
}

这篇关于如何通过类模板参数来提高::变种?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆