与汽车发电机相关的助推精神业力和助推变体"concepts"

Boost-spirit-karma and boost-variant "concepts" related to auto generators

本文关键字:concepts 发电机 汽车      更新时间:2023-10-16

我需要用其他对象提供的装饰对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类型OutputStreamable作为no-op。

怎么了?(

我真的开始质疑,当使用具有> 2层间接模板的库时,c++模板机制是否值得。也许我应该回到c -c。

编辑1:

Ok, Clang给了我一个合理的first错误…

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

现在我要弄清楚如何将未定义映射为无操作以获得干净的转换。这个精神文档条目(特别是这个)描述了我需要研究的内容。是否有一个由精神提供的通用的未定义类型,或者一个在增强中定义的类型,精神已经映射为无操作?

编辑2:

std::vector<boost::optional<boost::variant<..>>>开始看起来相当吸引人,因为精灵为他们提供了类型演绎。

我建议使用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<>