【问题标题】:boost karma - generate multiple strings from one attributeboost karma - 从一个属性生成多个字符串
【发布时间】:2014-10-26 23:19:55
【问题描述】:

我正在使用一个消耗成对向量的业力生成器 - 类似于 http://boost-spirit.com/home/articles/karma-examples/output-generation-from-a-list-of-key-value-pairs-using-spirit-karma/

我根据上面的文章构建了一个示例来显示我的问题

#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/karma.hpp>

namespace karma = boost::spirit::karma;
typedef std::pair<std::string, std::string > pair_type;

template <typename OutputIterator>    
struct keys_and_values : karma::grammar<OutputIterator, std::vector<pair_type>()>
{
    keys_and_values() : keys_and_values::base_type(query)
    {
        query =  *pair;
        // here is the interesting part
        pair  =  karma::string << ' ' << karma::string << ' ' << karma::string << karma::eol;
    }
karma::rule<OutputIterator, std::vector<pair_type>()> query;
karma::rule<OutputIterator, pair_type()> pair;
};

int main(int argc, char *argv[])
{
    typedef std::back_insert_iterator<std::string> sink_type;

    std::vector<pair_type> v;
    v.push_back(pair_type("key1", "value1"));
    v.push_back(pair_type("key2", "value2"));
    v.push_back(pair_type("key3", "value3"));

    std::string generated;
    sink_type sink(generated);
    keys_and_values<sink_type> g;

    bool result = karma::generate(sink, g, v);

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

    return 0;
}

我想要实现的是像“value1 key1 value1”这样的输出。通常它会输出“key1 value1”(但仅当您在我的示例中删除第三个 karma::string 时) 我已经尝试了很多带有语义操作的东西,例如

pair = karma::string[karma::_1 = karma::_val] ...

但是,这不起作用。我可能需要其他东西来从我的 std::pair 中获取价值。

这 2 个问题看起来很有趣,但没有解决我的问题 reuse parsed variable with boost karma How to access data of nested objects in boost::spirit::karma?

【问题讨论】:

  • 根据 Mike M 在您的第一个链接问题中的评论,您可以使用 like this

标签: c++ boost boost-spirit boost-spirit-karma


【解决方案1】:

虽然从技术上讲 karma::duplicate[] 在这里看起来很自然,但我可能会在这里使用本地:

更新:正如评论者所说,我误读并交换了键/值。在这里,BOOT_FUSION_ADAPT_STRUCT_NAMED 似乎是正常的!

BOOST_FUSION_ADAPT_STRUCT_NAMED(
    pair_type const, pair_as_vkv,
    (std::string, second)
    (std::string, first)
    (std::string, second)
)

而且,现在你可以写了

template <typename OutputIterator>
struct keys_and_values : karma::grammar<OutputIterator, std::vector<pair_type>()>
{
    keys_and_values() : keys_and_values::base_type(query)
    {
        query = *pair;
        pair = karma::string << ' ' << karma::string << ' ' << karma::string << karma::eol;
    }
    karma::rule<OutputIterator, std::vector<pair_type>()> query;
    karma::rule<OutputIterator, boost::fusion::adapted::pair_as_vkv()> pair;
};

事不宜迟:看吧Live On Coliru

输出

value1 key1 value1
value2 key2 value2
value3 key3 value3

完整列表

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/karma.hpp>

typedef std::pair<std::string, std::string> pair_type;

BOOST_FUSION_ADAPT_STRUCT_NAMED(
    pair_type const, pair_as_vkv,
    (std::string, second)
    (std::string, first)
    (std::string, second)
)

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

template <typename OutputIterator>
struct keys_and_values : karma::grammar<OutputIterator, std::vector<pair_type>()>
{
    keys_and_values() : keys_and_values::base_type(query)
    {
        query = *pair;
        pair = karma::string << ' ' << karma::string << ' ' << karma::string << karma::eol;
    }
    karma::rule<OutputIterator, std::vector<pair_type>()> query;
    karma::rule<OutputIterator, boost::fusion::adapted::pair_as_vkv()> pair;
};

int main(int argc, char *argv[])
{
    typedef std::back_insert_iterator<std::string> sink_type;

    std::vector<pair_type> v;
    v.push_back(pair_type("key1", "value1"));
    v.push_back(pair_type("key2", "value2"));
    v.push_back(pair_type("key3", "value3"));

    std::string generated;
    sink_type sink(generated);
    keys_and_values<sink_type> g;

    karma::generate(sink, g, v);

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

    return 0;
}

【讨论】:

  • +1。非常好,但我认为提问者想要value key value,这会使规则复杂化。编辑:Not so much.
  • @cv_and_he 哎呀。好决定。我认为我的更新答案赢得了优雅竞赛:)(我不得不visit the mailing list 以获得微妙的 const 正确性提示!)
  • 非常有趣,可惜我不能再给你一个 +1。 This 的灵感来自您的方法(以及“qi/reorder_struct.cpp”示例)。
  • 谢谢,它工作得很好:) 所以 phoenix 和 fusion 能够解决我的问题。我特别喜欢我不再需要语义动作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 2018-07-08
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 2020-12-11
  • 1970-01-01
相关资源
最近更新 更多