3

ペアのベクトルを消費するカルマジェネレーターを使用しています-http://boost-spirit.com/home/articles/karma-examples/output-generation-from-a-list-of-key-value-pairsに似ています-使用精神カルマ/

上記の記事に従って、私の問題を示す例を作成しました

#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」を出力します(ただし、私の例では3番目のカルマ::文字列を削除した場合のみ)私はすでにセマンティックアクションで多くのものを試しました.

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

しかし、それはうまくいきません。std::pair から値を取得するには、おそらく何か他のものが必要です。

これらの 2 つの質問は面白そうに見えましたが、私の問題を解決 しませんでしたブースト カルマで解析された変数を再利用 します ブースト::精神::カルマでネストされたオブジェクトのデータにアクセスする方法は?

4

1 に答える 1

3

技術的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;
}
于 2014-10-27T07:56:49.617 に答える