【问题标题】:Boost-spirit-karma and boost-variant "concepts" related to auto generators与自动发电机相关的 Boost-spirit-karma 和 boost-variant “概念”
【发布时间】:2023-03-24 05:25:01
【问题描述】:

我需要用其他对象提供的装饰反序列化 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 typeOutputStreamable 作为无操作。

什么给了? :(

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

编辑 1:

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

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

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

编辑 2:

std::vector&lt;boost::optional&lt;boost::variant&lt;..&gt;&gt;&gt; 开始看起来很有吸引力,因为精神为他们提供了类型推断。

【问题讨论】:

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


    【解决方案1】:

    我建议为此目的使用spirit::unused_type,因为它已经为 Spirit '已知',并且它具有预定义的 operator&lt;&lt;()(但任何其他类型都可以) - 并不是说​​你真的需要 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&lt;&gt;

    【讨论】:

    • 谢谢你,一如既往。因为我可以选择,所以我将提供undefined 的映射,因为它已经在我的 QI 代码中使用,它让我在自己的界面后面拥有防火墙精神:D 我开始看到 TMP 扩展带来的强大功能。只希望 C++0x 没有放弃“概念”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-12
    相关资源
    最近更新 更多