повысить карму — генерировать несколько строк из одного атрибута

Я использую карма-генаратор, который потребляет вектор пар — симуляция 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;
}

То, что я пытаюсь достичь, это вывод типа «значение1 ключ1 значение1». Обычно он выдает «key1 value1» (но только если вы удалите третью строку karma :: string в моем примере)
я уже пробовал много вещей с семантическими действиями, например

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

Однако это не работает. Возможно, мне нужно что-то еще, чтобы получить значение из моей std :: pair.

Эти 2 вопроса выглядели интересно, но не решили мою проблему
повторно использовать проанализированную переменную с повышенной кармой
Как получить доступ к данным вложенных объектов в boost :: spirit :: karma?

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;
};

Без лишних слов: посмотрите Жить на Колиру

Выход

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;
}
3

Другие решения


По вопросам рекламы [email protected]