我可以将BOOST_FUSION_ADAPT_STRUCT与继承的东西一起使用吗? [英] Can I use BOOST_FUSION_ADAPT_STRUCT with inherited stuff?

查看:250
本文介绍了我可以将BOOST_FUSION_ADAPT_STRUCT与继承的东西一起使用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有

struct cat
{
    int tail;
    int head;
};

struct bird
{
    int wing;
    int bursa;
};

如果我这样做...

struct wat : public cat, public bird
{

};

BOOST_FUSION_ADAPT_STRUCT(cat,tail,head)
BOOST_FUSION_ADAPT_STRUCT(bird, wing, bursa)
BOOST_FUSION_ADAPT_STRUCT(wat, wat::cat, wat::bird)

...我无法构建,但是如果我像下面那样显式引用继承的对象,那将是完全有效的.

... I cannot get a build, but if I explicit refer to the inherited objects like what's below, it's perfectly valid.

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
namespace qi = boost::spirit::qi;
struct wat
{
public:
    cat z;
    bird q;
};

BOOST_FUSION_ADAPT_STRUCT(cat,tail,head)
BOOST_FUSION_ADAPT_STRUCT(bird, wing, bursa)
BOOST_FUSION_ADAPT_STRUCT(wat, z, q)

是否有某种方法可以使第一个版本正常工作,从而使我可以适应具有公开身份的公共成员的结构?我绝对不想做BOOST_FUSION_ADAPT_STRUCT(wat,tail,head,wing,bursa),但这似乎是我可以找到的继承成员到达那里的唯一方法.

Is there some way to make the first version work, such that I can adapt a struct of inhereted public members? I definitely do NOT want to do BOOST_FUSION_ADAPT_STRUCT(wat,tail,head,wing,bursa) but this seems to be the only way to get there with inherited members I can find.

推荐答案

此处存在类似问题: c ++/boost融合处理父类

简短的问题:不,这不是功能.

Short question: no that's not a feature.

您可以使用聚合代替继承,

You can use aggregation instead of inheritance,

struct wat {
    cat _cat;
    bird _bird;
};

BOOST_FUSION_ADAPT_STRUCT(wat, _cat, _bird)

但是您不会神奇地获得扁平化的序列.

but you won't magically get a flattened sequence.

在处理融合序列的代码中,您可能想做的就是编写对已知基类的支持,并在适应序列成员的基础上处理这些基类.

What you might want to do in your code that treats fusion sequences, is code the support for known base classes and handle them in addition to the adapted sequence members.

在Coliru上直播

#include <boost/fusion/include/adapted.hpp>

struct cat {
    int tail;
    int head;
};

struct bird {
    int wing;
    int cloaca;
};

struct wat {
    cat _cat;
    bird _bird;
};

BOOST_FUSION_ADAPT_STRUCT(cat, tail, head)
BOOST_FUSION_ADAPT_STRUCT(bird, wing, cloaca)
BOOST_FUSION_ADAPT_STRUCT(wat, _cat, _bird)

#include <iostream>
#include <boost/fusion/include/at_c.hpp>

template <typename T, int N = 0> void print(T const& obj) {
    namespace fus = boost::fusion;
    if constexpr (fus::traits::is_sequence<T>::value) {
        if (N==0)
            std::cout << "{";

        if constexpr (N < fus::size(obj).value) {
            auto name = boost::fusion::extension::struct_member_name<T, N>::call();
            std::cout << ' ' << name << '=';
            print(fus::at_c<N>(obj));
            std::cout << ';';
            print<T, N+1>(obj);
        } else {
            std::cout << " }";
        }
    } else {
        std::cout << obj;
    }
}

int main() {
    print(wat { {1,2}, {3,4} });
}

打印

{ _cat={ tail=1; head=2; }; _bird={ wing=3; cloaca=4; }; }

带有基址硬编码列表的演示

在Coliru上直播

#include <boost/fusion/include/adapted.hpp>

struct cat {
    int tail;
    int head;
};

struct bird {
    int wing;
    int cloaca;
};

struct wat : cat, bird {
    int something;
    int extra;

    wat(int tail, int head, int wing, int cloaca, int something, int extra)
        : cat{tail, head}, bird{wing, cloaca}, something(something), extra(extra)
    { }
};

BOOST_FUSION_ADAPT_STRUCT(cat, tail, head)
BOOST_FUSION_ADAPT_STRUCT(bird, wing, cloaca)
BOOST_FUSION_ADAPT_STRUCT(wat, something, extra)

#include <iostream>
#include <boost/fusion/include/at_c.hpp>

template <typename... KnownBases>
struct Demo {
    template <typename T, int N = 0> static void print(T const& obj, bool outer_sequence_braces = true) {
        namespace fus = boost::fusion;
        if constexpr (fus::traits::is_sequence<T>::value) {
            if (N==0)
            {
                if (outer_sequence_braces) std::cout << "{";
                print_bases<KnownBases...>(obj);
            }

            if constexpr (N < fus::size(obj).value) {
                auto name = boost::fusion::extension::struct_member_name<T, N>::call();
                std::cout << ' ' << name << '=';
                print(fus::at_c<N>(obj), true/*inner sequences get braces*/);
                std::cout << ';';
                print<T, N+1>(obj, outer_sequence_braces);
            } else {
                if (outer_sequence_braces) std::cout << " }";
            }
        } else {
            std::cout << obj;
        }
    }

    template <typename Base, typename T> static bool print_base(T const& obj) {
        if constexpr (not std::is_same<Base, T>() && std::is_base_of<Base, T>())
            print(static_cast<Base const&>(obj), false);
        return true;
    }

    template <typename... Bases, typename T> static void print_bases(T const& obj) {
        bool discard[] = { print_base<Bases>(obj)... };
        (void) discard;
    }
};

int main() {
    Demo<cat, bird>::print(wat { 1, 2, 3, 4, 5, 6 });
}

打印

{ tail=1; head=2; wing=3; cloaca=4; something=5; extra=6; }

这篇关于我可以将BOOST_FUSION_ADAPT_STRUCT与继承的东西一起使用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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