Вывод типа boost::variant с использованием boost::spirit::karma

Я пытаюсь вывести параметры, они могут быть либо одним параметром, либо вектором параметров. Следующий код не делает то, что я хотел бы сделать:

#include <iostream>
#include <string>
#include <boost/variant.hpp>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;

typedef std::vector<int> ParameterList;
typedef boost::variant<int, ParameterList> Parameter;

main()
{
    using karma::int_;
    using karma::eol;
    using karma::lit;

    std::string generated;
    std::back_insert_iterator<std::string> sink(generated);

    karma::rule<std::back_insert_iterator<std::string>, ParameterList()> parameterListRule = int_ % lit(", ");
    karma::rule<std::back_insert_iterator<std::string>, Parameter()> parameterRule = (int_ | parameterListRule) << eol;

    karma::generate(sink, parameterRule, 1); // Works
    karma::generate(sink, parameterRule, ParameterList{1, 2}); // Doesn't work
    std::cout << generated << "\n";
}

(Реальный код имеет другие типы параметров, а не только int, и я не могу просто сделать все ParameterList.)

Я не совсем понимаю, как это заставить работать, тем более, что аналогичная конструкция для парсинга у меня прекрасно работает с boost::spirit::qi.


person Xoph    schedule 06.08.2013    source источник


Ответы (1)


Во втором вызове вы не поместили вариант в генератор, но правило ожидает его.

#include <iostream>
#include <string>
#include <boost/variant.hpp>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;

typedef std::vector<int> ParameterList;
typedef boost::variant<int, ParameterList> Parameter;

main()
{
    using karma::int_;
    using karma::eol;
    using karma::lit;

    std::string generated;
    std::back_insert_iterator<std::string> sink(generated);

    karma::rule<std::back_insert_iterator<std::string>, ParameterList()> parameterListRule = int_ % lit(", ");
    karma::rule<std::back_insert_iterator<std::string>, Parameter()> parameterRule = (int_ | parameterListRule) << eol;

    karma::generate(sink, parameterRule, 1); // Works
    // use variant here:
    Parameter test(ParameterList{1, 2});
    karma::generate(sink, parameterRule, test);
    std::cout << generated << "\n";
}
person Mike M    schedule 07.08.2013
comment
Я думал, что смогу упростить свою настоящую проблему настолько, а затем испортил ее, представив эту глупую ошибку. Спасибо и извините, моя настоящая проблема теперь здесь. - person Xoph; 07.08.2013