Буст-дух-карма и буст-вариант "концепции", связанные с автогенераторами

Мне нужно десериализовать std::vector<boost::variant<..>> с отделкой из других предметов.

Одна из вещей, которую включает "украшение" - пустая запись в векторе. Я ударил кирпичную стену в моей реальной реализации. Однако мне удалось обернуть его. Код, который компилируется:

#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>

namespace karma = boost::spirit::karma;

typedef boost::variant<boost::int32_t, boost::int64_t> custom_variant;

int main()
{
    using karma::generate;

    custom_variant v;

    std::string temp;

    std::back_insert_iterator<std::string> x(temp);

    std::cout << v;

    karma::generate(x, karma::auto_, v);
}

Оскорбительные изменения, которые пытаются реализовать "неопределенный" тип вместе с требуемой концепцией.

#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>

namespace karma = boost::spirit::karma;

struct undefined{};

std::ostream & operator<<(std::ostream & out, undefined const & undefined)
{
    return out;
}

typedef boost::variant<undefined,boost::int32_t, boost::int64_t> custom_variant;

int main()
{
    using karma::generate;

    custom_variant v;

    std::string temp;

    std::back_insert_iterator<std::string> x(temp);

    std::cout << v;

    karma::generate(x, karma::auto_, v);
}

Если я закомментирую karma::generate шаг, std::cout является допустимым выражением (Boost:: option OutputStreamable). Дух требует, чтобы генераторам были даны типы, которые OutputStreamable (Дух:: карма OutputStreamable) и вариант выше должен быть OutputStreamable так как я сделал undefined тип OutputStreamable как неоперативный.

Что дает?:(

Я действительно начинаю сомневаться в том, стоит ли использовать механизм шаблонов C++ при использовании библиотек с> 2 уровнями косвенности шаблонов. Возможно, я должен вернуться к прямой.

Изменить 1:

Хорошо, Clang дал мне разумный first ошибка...

error: no type named 'properties' in 'boost::spirit::karma::no_auto_mapping_exists'

Теперь я должен выяснить, как отобразить неопределенное как неактивное, чтобы получить чистое преобразование. Эта запись духа документацииэто в частности) описывает то, что мне нужно посмотреть. Существует ли общий неопределенный тип, предоставленный духом, или тип, определенный в boost, этот дух уже отображается как неоперативный?

Изменить 2:

std::vector<boost::optional<boost::variant<..>>> начинает выглядеть довольно привлекательно, так как дух обеспечивает им вывод типов.

1 ответ

Решение

Я бы предложил использовать spirit::unused_type для этой цели, поскольку он уже "известен" Духу и имеет operator<<() предопределенный (но подойдет любой другой тип) - не то, что вам действительно нужен этот оператор для кармы.

Кроме того, вы должны предоставить специализацию для create_generator (как вы и подозревали):

namespace boost { namespace spirit { namespace traits
{
    template <>
    struct create_generator<spirit::unused_type>
    {
        typedef spirit::karma::eps_type type;

        static type call()
        {
            return spirit::karma::eps;
        }
    };
}}}

который будет отображать unused_type в karma::eps, Похоже, это именно то, что вам нужно, как eps ест атрибут, ничего не генерируя, при этом всегда успешно. Если вы идете по этому маршруту, вам не нужно использовать optional<>,

Другие вопросы по тегам