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

时间:2011-04-14 14:34:28

标签: c++ boost-spirit boost-variant boost-spirit-karma

我需要使用其他对象提供的装饰反序列化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 :: variant OutputStreamable)。 Spirit要求生成器的类型为OutputStreamable(spirit :: karma OutputStreamable),上面的变体应为OutputStreamable,因为我已经undefined类型{{1作为无操作。

是什么给出的? :(

我真的开始质疑天气,当使用带有&gt;的库时,C ++模板机制是值得的。 2级模板间接。也许我应该回到直接c。

修改1:

好的,Clang给了我一个明智的OutputStreamable错误......

first

现在我想弄清楚如何将undefined映射为无操作以获得干净的转换。这个spirit documentation entry(以及具体的this)描述了我需要研究的内容。是否存在由精神提供的通用未定义类型或者在boost中定义的类型,该精神已经映射为无操作?

编辑2:

error: no type named 'properties' in 'boost::spirit::karma::no_auto_mapping_exists'开始看起来很有吸引力,因为精神为它们提供了类型推导。

1 个答案:

答案 0 :(得分:3)

我建议使用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。这似乎正是你所需要的,因为eps在没有生成任何东西的情况下吃属性,而总是成功。如果你走这条路线,你将不需要使用optional<>