Буст-дух-карма и буст-вариант "концепции", связанные с автогенераторами
Мне нужно десериализовать 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<>
,