Я пытаюсь использовать карму для генерации списка строк через запятую, из вектора структур, которые содержат функцию-член, которая обеспечивает строку.
Хотя я могу сгенерировать вывод одной строки с помощью phoenix :: bind, и я могу сгенерировать вывод csv из вектора строк, я борюсь за объединение двух подходов.
В следующем примере первое правило работает нормально, второе не скомпилируется (с использованием VS2013, boost 1.57), что приводит к ошибке феникса: «невозможно преобразовать из« std :: vector> * »в« foo * »», поэтому семантическое действие, которое будет работать для одного экземпляра структуры, в этом случае неверно. Является ли единственным ответом использовать адаптер Fusion?
#include <iostream>
#include <vector>
#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace karma = boost::spirit::karma;
namespace phx = boost::phoenix;
struct foo
{
std::string f() const { return "bar"; }
};
int main()
{
std::string output;
typedef std::back_insert_iterator< std::string > iterator;
iterator it(output);
// this works:
std::vector<std::string> svec = { "foo", "bar", "baz" };
karma::rule< iterator, std::vector<std::string>() > svec_rule = karma::string % ',';
karma::generate(it, svec_rule, svec);
std::cerr << output << '\n';
// but this won't compile
std::vector<foo> vfoo(3);
karma::rule< iterator, std::vector<foo>&() > vfoo_rule = karma::string[karma::_1 = phx::bind(&foo::f, karma::_val)] % ',';
karma::generate(it, vfoo_rule, vfoo);
std::cerr << output << '\n';
}
_val
представляет vector<foo>
в этом правиле. Вы не можете очень хорошо назвать foo::f
на векторе.
Вместо этого сделайте правило для foo
(или использовать attr_cast<>
):
karma::rule<iterator, foo()> foo_rule = karma::string [ karma::_1 = phx::bind(&foo::f, karma::_val) ];
karma::generate(it, foo_rule % ',', vfoo);
std::cerr << output << '\n';
Печать bar,bar,bar