当前位置: 首页 > 知识库问答 >
问题:

使 FUSION 工作以显示结构的内容

舒博雅
2023-03-14

以下代码的目的是显示结构的内容。这是基于这个答案。

#include <iostream>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/bind.hpp>

struct Node {
    int a = 4;
    double b = 2.2;
};

BOOST_FUSION_ADAPT_STRUCT(Node, b)

struct print_visitor {
    template <class Index, class C> void operator()(Index, C &c) {
        std::cout << boost::fusion::extension::struct_member_name<
                         C, Index::value>::call() << "="
                  << boost::fusion::at<Index>(c) << std::endl;
    }
};

template <class C> void print_fields(C &c) {
    typedef boost::mpl::range_c<
        int, 0, boost::fusion::result_of::size<C>::type::value> range;
    boost::mpl::for_each<range>(
        boost::bind<void>(print_visitor(), _1, boost::ref(c)));
}

int main() {
    Node n;
    print_fields(n);
}

编译器(gcc 版本 4.8.2)抱怨:

无效使用不完整类型的结构提升::融合::result_of::at

原因是什么,我该如何解决这个问题?

以下是编译器的完整输出:

-*- mode: compilation; default-directory: "~/SearchLib/AstarWithPolicies/temp/" -*-
Compilation started at Thu Dec 10 11:54:27

make -k 
g++ -Wall -Wextra -Werror -std=c++11 -pedantic -I ~/boost_1_59_0 -I /usr/include/cairomm-1.0/ -I /usr/include/cairo/ -I /usr/include/sigc++-2.0/ -I /usr/lib/x86_64-linux-gnu/sigc++-2.0/include/ -I /usr/include/freetype2/ -g -c temp.cpp
In file included from /home/meir/boost_1_59_0/boost/utility/enable_if.hpp:15:0,
                 from /home/meir/boost_1_59_0/boost/fusion/support/tag_of.hpp:11,
                 from /home/meir/boost_1_59_0/boost/fusion/support/category_of.hpp:12,
                 from /home/meir/boost_1_59_0/boost/fusion/adapted/struct/detail/extension.hpp:14,
                 from /home/meir/boost_1_59_0/boost/fusion/adapted/struct/adapt_struct.hpp:27,
                 from temp.cpp:7:
/home/meir/boost_1_59_0/boost/core/enable_if.hpp: In instantiation of ‘struct boost::lazy_disable_if_c<false, boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> > >’:
/home/meir/boost_1_59_0/boost/core/enable_if.hpp:70:10:   required from ‘struct boost::lazy_disable_if<boost::is_const<Node>, boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> > >’
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5:   required by substitution of ‘template<class N, class Sequence> constexpr typename boost::lazy_disable_if<boost::is_const<Sequence>, boost::fusion::result_of::at<Sequence, N> >::type boost::fusion::at(Sequence&) [with N = mpl_::integral_c<int, 0>; Sequence = Node]’
temp.cpp:26:48:   required from ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34:   required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50:   required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25:   required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97:   required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48:   required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62:   required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19:   required from here
/home/meir/boost_1_59_0/boost/core/enable_if.hpp:63:30: error: invalid use of incomplete type ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
     typedef typename T::type type;
                              ^
In file included from /home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic/begin.hpp:14:0,
                 from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/detail/for_each.hpp:11,
                 from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/for_each.hpp:12,
                 from /home/meir/boost_1_59_0/boost/fusion/include/for_each.hpp:11,
                 from temp.cpp:9:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:53:16: error: declaration of ‘struct boost::fusion::result_of::at<Node, mpl_::integral_c<int, 0> >’
         struct at;
                ^
temp.cpp: In instantiation of ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’:
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34:   required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50:   required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25:   required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97:   required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48:   required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62:   required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19:   required from here
temp.cpp:26:48: error: no matching function for call to ‘at(Node&)’
                   << boost::fusion::at<Index>(c) << std::endl;
                                                ^
temp.cpp:26:48: note: candidates are:
In file included from /home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic/begin.hpp:14:0,
                 from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/detail/for_each.hpp:11,
                 from /home/meir/boost_1_59_0/boost/fusion/algorithm/iteration/for_each.hpp:12,
                 from /home/meir/boost_1_59_0/boost/fusion/include/for_each.hpp:11,
                 from temp.cpp:9:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: note: template<class N, class Sequence> constexpr typename boost::lazy_disable_if<boost::is_const<Sequence>, boost::fusion::result_of::at<Sequence, N> >::type boost::fusion::at(Sequence&)
     at(Sequence& seq);
     ^
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:102:5: note:   substitution of deduced template arguments resulted in errors seen above
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: note: template<class N, class Sequence> constexpr typename boost::fusion::result_of::at<const Sequence, N>::type boost::fusion::at(const Sequence&)
     at(Sequence const& seq);
     ^
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: note:   template argument deduction/substitution failed:
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp: In substitution of ‘template<class N, class Sequence> constexpr typename boost::fusion::result_of::at<const Sequence, N>::type boost::fusion::at(const Sequence&) [with N = mpl_::integral_c<int, 0>; Sequence = Node]’:
temp.cpp:26:48:   required from ‘void print_visitor::operator()(Index, C&) [with Index = mpl_::integral_c<int, 0>; C = Node]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:315:34:   required from ‘void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = print_visitor; A = boost::_bi::list1<mpl_::integral_c<int, 0>&>; A1 = boost::arg<1>; A2 = boost::reference_wrapper<Node>]’
/home/meir/boost_1_59_0/boost/bind/bind.hpp:907:50:   required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = mpl_::integral_c<int, 0>&; R = void; F = print_visitor; L = boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> >; boost::_bi::bind_t<R, F, L>::result_type = void]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:78:25:   required from ‘static void boost::mpl::aux::for_each_impl<false>::execute(Iterator*, LastIterator*, TransformFunc*, F) [with Iterator = boost::mpl::r_iter<mpl_::integral_c<int, 0> >; LastIterator = boost::mpl::r_iter<mpl_::integral_c<int, 1> >; TransformFunc = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:105:97:   required from ‘void boost::mpl::for_each(F, Sequence*, TransformOp*) [with Sequence = boost::mpl::range_c<int, 0, 1>; TransformOp = boost::mpl::identity<mpl_::na>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
/home/meir/boost_1_59_0/boost/mpl/for_each.hpp:118:48:   required from ‘void boost::mpl::for_each(F, Sequence*) [with Sequence = boost::mpl::range_c<int, 0, 1>; F = boost::_bi::bind_t<void, print_visitor, boost::_bi::list2<boost::arg<1>, boost::reference_wrapper<Node> > >]’
temp.cpp:34:62:   required from ‘void print_fields(C&) [with C = Node]’
temp.cpp:39:19:   required from here
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:107:5: error: invalid use of incomplete type ‘struct boost::fusion::result_of::at<const Node, mpl_::integral_c<int, 0> >’
/home/meir/boost_1_59_0/boost/fusion/sequence/intrinsic_fwd.hpp:53:16: error: declaration of ‘struct boost::fusion::result_of::at<const Node, mpl_::integral_c<int, 0> >’
         struct at;
                ^
make: *** [all] Error 1

Compilation exited abnormally with code 2 at Thu Dec 10 11:54:27

共有1个答案

危晨
2023-03-14

我发现这篇文章是因为我正在练习MPL的使用。我来到这里,因为我想打印你成功的struct_member_name。简短的答案是包括

< code > BOOST _ FUSION _ ADAPT _ STRUCT 仅执行此操作,它不会为目标创建序列。如果您以访问名称的相同方式访问值,它就可以工作了。

boost::fusion::extension::access::struct_member<C, Index::value>::template apply<C>::call(x)

返回感兴趣的值。但当然,总有更好的方法,因为很多代码都很难看。一旦将序列应用到类中,一切都会变得简单。现在,我没有找到迭代和传递类型的<code>for_each</code>和<code>fusion::for_each</code>解引用值并将其传递给函子。因此,我从<code>boost\fusion\sequence\io\out中获取了一些代码。hpp在迭代器范围内移动。

此示例以迭代器方式打印数据,并直接使用 fusion 的 IO。我敢肯定我错过了很多东西,但这是我真正编写编译时代码的第一天。谢谢你的问题,如果没有它,我可能不会走得这么远!

#include <iostream>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
//https://www.boost.org/doc/libs/1_78_0/libs/fusion/doc/html/fusion/support/deduce_sequence.html
#include <boost/bind/bind.hpp>
#include <boost/fusion/iterator/distance.hpp>
struct test {
    int val;
    std::string name;
};
BOOST_FUSION_ADAPT_STRUCT(test,val,name)

//the origanal with changes
struct print_class
{
    template <class Index, typename T>
    void operator()(Index, T& x) const
    {
        std::cout << "from print_class: " << boost::fusion::extension::struct_member_name<T, Index::value>::call()
            << " = " << boost::fusion::at<Index>(x) << std::endl;
    }
};

using namespace boost::placeholders;
template <class C> void print_fields(C& c) {

    typedef boost::mpl::range_c<
        int, 0, boost::fusion::result_of::size<C>::type::value> range;

    boost::mpl::for_each<range>(
        boost::bind<void>(print_class(), _1, boost::ref(c)));
}

//I could not find anything like this in the fusion namespace, so...
//T is a fusion iterator
namespace boost::fusion {
    template <typename T>
    auto get_name(){return  boost::fusion::extension::struct_member_name<T::seq_type, T::index::value>::call();
    }
}

//shamelessly stolen from fusion/io....
namespace {
    using namespace boost;
    namespace bf = fusion;
    struct print_sequence_loop
    {
        template <typename OS, typename First, typename Last>
        static void call(OS&, First&, Last&, mpl::true_)
        {
        }

        template <typename OS, typename First, typename Last>
        static void call(OS& os, First& first, Last& last, mpl::false_)
        {
            bf::result_of::equal_to<
                typename bf::result_of::next<First>::type
                , Last
            >is_last;

            //The code that prints
            os << bf::get_name<First>() << " = ";
            os << *first << std::endl;
            //End the code that prints

            call(os, fusion::next(first), last, is_last);
        }

        template <typename OS, typename First, typename Last>
        static void call(OS& os, First const& first, Last const& last)
        {
            bf::result_of::equal_to<First, Last> eq;
            call(os, first, last, eq);
        }
    };
    template <typename OS, typename Sequence>
    inline void print_sequence(OS& os, Sequence& seq)
    {
        print_sequence_loop::call(os, fusion::begin(seq), fusion::end(seq));
    }
}

using boost::fusion::operators::operator<<;

int main() {
    test the_test{ 12,"this is me" };
    print_sequence(std::cout, the_test);
    std::cout << '\n';
    print_fields(the_test);
    std::cout << "\n\n this is using fusions OS\n";
    std::cout << the_test << std::endl;
}

GCC演示,它与MSVC一起工作。

 类似资料:
  • 我需要将Excel表内容显示到同一Excel文件中的另一个表。这里我有两个表和。我试图通过使用或来设置的单元格值。(我尝试了这两个公式。) 我得到了公式或而不是单元格中的结果。 “计算”选项是自动的,单元格不是文本,它显示为“常规”。 打开时,Excel显示: 双击单元格,结果显示:

  • 当我在MySQL Workbench中查询一个表时,没有显示任何结果,结果部分只是空白,没有网格或任何东西。然而,如果我导出数据,它就在那里。直到几天前,一切都很顺利。 查询设置: 最大长度=65536 没有查询工作,一个例子将是

  • 我正在尝试在UI上显示树结构。但是得到一个错误。 无法绑定到“target”,因为它不是“i”的已知属性。(“v*ngFor=”让文件项 虽然这个属性存在于我的json文件中,如下所示: 我的html文件如下: 我无法找出这次失败的原因。我已经尝试了所有可能的条件,我可以申请使它工作。请帮我解决这个问题

  • 我正在尝试使用boost::property_tree反序列化JSON数据。我已经设置了一个boost fusion序列来识别结构成员元素的类型,并使用一个函数来反序列化一个适当的JSON树。它过去对于包含普通数据类型的结构工作得很好。当我尝试对包含结构的结构应用相同的操作时,逻辑会失败并导致编译器错误。有人能看出我错在哪里吗? 错误消息:1

  • 我们使用VSTS构建使用ASP.Net模板。我们传递MSBuild参数如下- /p:DeployOnBuild=true /p:WebP发布方法=包 /p:包作为单一文件=真 /p:跳过验证配置=真 /p:包位置=“$(build.artifactstage 目录)\” 我们没有看到任何构建错误。从日志中,我们观察到一条线 - C:\Windows\Microsoft.NET\Framework\

  • 使用AngularJs,我有一个双循环来显示数据,还有一个按年过滤。 当,对于给定的一年,我没有结果,我想显示消息"没有结果...",但由于双循环,我无法让它工作 这是一个演示http://plnkr.co/edit/OSWSyXk8bnvmj1rFwHJ0?p=preview 我要在何时显示的div 要查看没有结果的示例,请在年度下拉列表中选择“2013-2014” 非常感谢