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

Мне нужно десериализовать 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::generatestep, std::cout является допустимым выражением (Boost :: variable OutputStreamable).Дух требует, чтобы генераторам были даны типы, которые являются OutputStreamable (Spirit :: Karma OutputStreamable), и вариант выше должен быть OutputStreamable, так как я сделал undefined type OutputStreamable какno-op.

Что дает?: (

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

Редактировать 1:

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

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

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

Edit 2:

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

1 Ответ

3 голосов
/ 14 апреля 2011

Я бы предложил использовать 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<>.

...