【问题标题】:Inconsistent Generator directive column behavior in boost karma提升业力中不一致的生成器指令列行为
【发布时间】:2017-05-01 13:40:29
【问题描述】:

我正在编写 karma 生成器来生成 HTML 页面,但我在使用 column 指令时遇到了不一致的行为。 这很可能是我对其工作原理的理解。

基本上我正在生成一个网格,它要求我在每出现 2 次数据后插入一些分隔符。

以下是我用来进行试运行的基本程序。

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/struct.hpp>
#include <boost/fusion/include/nview.hpp>
#include <boost/assign/std/vector.hpp>

namespace fusion = boost::fusion;
namespace karma = boost::spirit::karma;

///////////////////////////////////////////////////////////////////////////////
namespace client
{
    //  Our employee struct
    struct employee
    {
        int num;
        std::string datatype;
        std::string dataname;
        std::string inputicon;
    };

    // define iterator type
    typedef std::back_insert_iterator<std::string> iterator_type;

}

BOOST_FUSION_ADAPT_STRUCT(
        client::employee,
        (int, num)
                (std::string, datatype)
                (std::string, dataname)
                (std::string, inputicon)
)

///////////////////////////////////////////////////////////////////////////////
int main()
{
    std::string str;

    // some employees
    client::employee john = { 25, "int", "sra_command","fa fa-wrench" };
    client::employee mary = { 25, "float", "swt_command","fa fa-wrench" };
    client::employee tom = { 25, "double", "msc_command","fa fa-mobile" };

    // now make a list of all employees and print them all
    std::vector<client::employee> employees;
    {
        using namespace boost::assign;
        employees += john, mary, tom;
    }

    {
        typedef
        fusion::result_of::as_nview<client::employee const, 1, 2, 3>::type
                names_and_salary;


        karma::rule<client::iterator_type, names_and_salary()> small_box  =
                                                   "<startofblock>"  <<  karma::string << "<after_first>"
                                                                    << karma::string << "<after_second>"
                                                                    << karma::string << "<after_third>";

        std::string generated;
        typedef std::back_insert_iterator<std::string> sink_type;
        sink_type sink(generated);
        karma::generate_delimited(sink, karma::columns(2,karma::string("nth_delimiter"))[small_box % karma::eol],karma::space,employees );

        std::cout << generated << std::endl;
    }
    return 0;
}

上面生成以下输出:

<startofblock>int<after_first>sra_command<after_second>fa fa-wrench<after_third> 
 nth_delimiter<startofblock>float<after_first>swt_command<after_second>fa fa-wrench<after_third> 
 nth_delimiter<startofblock>double<after_first>msc_command<after_second>fa fa-mobile<after_third> nth_delimiter

如前所述,第 n 个分隔符出现在每一代之后,而不是每一秒。

预期的输出是

<startofblock>int<after_first>sra_command<after_second>fa fa-wrench<after_third> 
<startofblock>float<after_first>swt_command<after_second>fa fa-wrench<after_third>  
 nth_delimiter<startofblock>double<after_first>msc_command<after_second>fa fa-mobile<after_third> 

【问题讨论】:

  • 预期输出是什么
  • 用 cmets 更新答案
  • 有了 columns() 你得到一个尾随的nth_delimiter 反正。就是这样指定的。
  • 是时候再次点击文档来弄清楚如何实现这一点:(
  • 我刚刚发布了两种方法,并附赠解释了为什么没有达到您的期望。希望对您有所帮助。

标签: boost boost-spirit boost-spirit-karma


【解决方案1】:

我认为这接近您想要实现的目标。就像我说的那样,最后一次(不完整的)运行仍将被 nth_delimiter 标签“终止”:

Live On Coliru

#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/struct.hpp>
#include <boost/fusion/include/nview.hpp>

///////////////////////////////////////////////////////////////////////////////
namespace client {
    struct employee
    {
        int num;
        std::string datatype;
        std::string dataname;
        std::string inputicon;
    };

    typedef std::back_insert_iterator<std::string> iterator_type;
}

BOOST_FUSION_ADAPT_STRUCT(client::employee, /*num,*/ datatype, dataname, inputicon)

///////////////////////////////////////////////////////////////////////////////
int main() {
    // some employees
    std::vector<client::employee> const employees {
        { 25, "int",    "sra_command","fa fa-wrench" },
        { 26, "float",  "swt_command","fa fa-wrench" },
        { 27, "double", "msc_command","fa fa-mobile" },
        { 28, "int",    "sra_command","fa fa-wrench" },
        { 29, "float",  "swt_command","fa fa-wrench" },
        { 30, "double", "msc_command","fa fa-mobile" },
        { 31, "int",    "sra_command","fa fa-wrench" },
        { 32, "float",  "swt_command","fa fa-wrench" },
        { 33, "double", "msc_command","fa fa-mobile" },
    };

    // now print them all
    std::string generated;
    {
        using namespace boost::spirit::karma;

        using Sink = client::iterator_type;
        //using Attr = boost::fusion::result_of::as_nview<client::employee const, 1, 2, 3>::type;
        using Attr = client::employee;
        rule<Sink, Attr()> small_box  = "<B>" << string << "<1>" << string << "<2>" << string << "<3>";

        generate(Sink(generated), columns(2, "<nth_delimiter>\n") [+small_box], employees);
    }

    std::cout << generated << std::endl;
}

打印

<B>int<1>sra_command<2>fa fa-wrench<3><B>float<1>swt_command<2>fa fa-wrench<3><nth_delimiter>
<B>double<1>msc_command<2>fa fa-mobile<3><B>int<1>sra_command<2>fa fa-wrench<3><nth_delimiter>
<B>float<1>swt_command<2>fa fa-wrench<3><B>double<1>msc_command<2>fa fa-mobile<3><nth_delimiter>
<B>int<1>sra_command<2>fa fa-wrench<3><B>float<1>swt_command<2>fa fa-wrench<3><nth_delimiter>
<B>double<1>msc_command<2>fa fa-mobile<3><nth_delimiter>

奖金:

smallbox % eol 的问题在于smallbox 是一个元素,而eol 也是:

    generate(Sink(generated), columns(4, "<nth_delimiter>") [small_box % eol], employees);

Live On Coliru

<B>int<1>sra_command<2>fa fa-wrench<3>
<B>float<1>swt_command<2>fa fa-wrench<3>
<nth_delimiter><B>double<1>msc_command<2>fa fa-mobile<3>
<B>int<1>sra_command<2>fa fa-wrench<3>
<nth_delimiter><B>float<1>swt_command<2>fa fa-wrench<3>
<B>double<1>msc_command<2>fa fa-mobile<3>
<nth_delimiter><B>int<1>sra_command<2>fa fa-wrench<3>
<B>float<1>swt_command<2>fa fa-wrench<3>
<nth_delimiter><B>double<1>msc_command<2>fa fa-mobile<3><nth_delimiter>

【讨论】:

  • 这太棒了!一段时间以来一直想弄清楚:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多