与汽车发电机有关的Boost-spirit-karma和Boost-variant“概念”

问题描述

| 我需要将“ 0”反序列化为其他对象提供的装饰。 “装饰”启用的功能之一是向量中的空条目。在我的实际实现中,我遇到了一堵砖墙。但是,我设法缩小包装。编译代码
#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,v);
}
如果我注释掉
karma::generate
步骤,则
std::cout
是有效表达式(Boost :: variant
OutputStreamable
)。 Spirit要求生成器的类型为
OutputStreamable
(spirit :: karma
OutputStreamable
),并且上面的变体应为
OutputStreamable
,因为我将
undefined
类型
OutputStreamable
设为无操作。 是什么赋予了 ? :( 我真的开始质疑,当使用具有大于2个级别的模板间接性的库时,C ++模板机制是值得的。也许我应该回到直线c。 编辑1: 好吧,lang给了我一个明智的
first
错误...
error: no type named \'properties\' in \'boost::spirit::karma::no_auto_mapping_exists\'
现在,我要弄清楚如何将undefined映射为no-op以获得清晰的转换。这个精神文档条目(尤其是本文档)描述了我需要研究的内容。 Spirit是否提供了一个通用的未定义类型,或者是否已经将其映射为no-op? 编辑2: spirit13ѭ开始显得很吸引人,因为精神为他们提供了类型演绎。     

解决方法

我建议为此目的使用
spirit::unused_type
,因为它已经为Spirit提供了“已知”并且预定义了
operator<<()
(但是其他任何类型都可以)-并不是说您真的需要Karma运算符。 此外,您还必须为
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
。这似乎正是您所需要的,因为s20ѭ总是在成功的情况下不产生任何东西就吃了该属性。如果走这条路线,您将不需要使用
optional<>
。