1

我需要将值映射到 std::string (使用以下映射和 BOOST_FUSION_ADAPT_STRUCT )

    std::map< TYPEX, std::string> author2name;
    struct Emp
   {
     std::string name;
     TYPEX author;
   };

使用以下代码,我想生成我的输出:

karma::rule< it, std::string()> quote = '"' >> karma::string >> '"';
karma::rule< it, Emp> emp = karma::delimit('\t')[ quite << quite[ author2name[ karma::_1] ]];

Emp x;
karma::generate( std::ostream_iterator<char>(std::cout), emp, x);

但它不编译。

有没有办法我可以写这样的标题:

karma::rule< it, std::vector<std::string>()> header = karma::delimit('\t')[ % quote];
karma::rule< it, Emp> emp = header >> karma::eol >> karma::delimit('\t')[ quite << quite[ author2name[ karma::_1] ]];

karma::generate( std::ostream_iterator<char>(std::cout), {"A", "B", "C"},emp, x);
4

1 回答 1

3

那里有许多小剪纸让你死了:)

工作示例:

Live On Coliru

#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <map>

namespace karma = boost::spirit::karma;
namespace phx   = boost::phoenix;

enum TYPEX { AUTHOR1, AUTHOR2, AUTHOR3, AUTHOR4 };

std::map<TYPEX, std::string> author2name;
struct Emp {
    std::string name;
    TYPEX author;
};

BOOST_FUSION_ADAPT_STRUCT(Emp, name, author) // boost 1_59
//BOOST_FUSION_ADAPT_STRUCT(Emp, (std::string, name)(std::string, author)) // older boost

int main() {
    using it = boost::spirit::ostream_iterator;

    karma::rule<it, std::string()> quote;
    karma::rule<it, TYPEX()> author;
    karma::rule<it, Emp()> emp;

    {
        using namespace karma;
        quote  %= '"' << string << '"';
        author  = quote [ _1 = phx::ref(author2name)[ _val ] ];
        emp    %= delimit('\t')[ quote << author ];
    }

    Emp x { "one", AUTHOR2 };
    author2name[AUTHOR2] = "TWO!";
    std::cout << karma::format(emp, x);
}

印刷:

"one"   "TWO!"  

引起麻烦的事情:

  • 建议使用boost::spirit::ostream_iteratorkarma::format更用户友好的 API
  • 在 上添加缺少的括号emp

    karma::rule<it, Emp()> emp;
    

    注意:最近的提升(1_59 IIRC)不再需要这些。这就是为什么我只在 Coliru 上发现的

  • 这里:

    quote[ author2name[ karma::_1] ]
    

    您将 [] 索引到std::mapusing ... 中qi::_1。那不能编译。你想要的是调用operator[]. 您必须包含 Phoenix 标头并强制author2name成为 Phoenix 参考演员:

    quote [ _1 = phx::ref(author2name)[_1] ]
    

    另请注意,分配回_1很重要!

  • 此外,要在存在语义操作的情况下拥有自动规则,您需要使用分配规则%=(否则 Karma 将抑制所有自动属性传播)

于 2015-10-09T19:27:24.307 回答