与boost :: karma

时间:2018-09-07 14:55:11

标签: boost boost-spirit boost-spirit-qi boost-fusion boost-spirit-karma

我不确定这是否与Error when adapting a class with BOOST_FUSION_ADAPT_ADT有关,但即使如此,其背后的问题仍未得到回答/仍然失败,请参见作者Error when adapting a class with BOOST_FUSION_ADAPT_ADT的评论。 (我使用了增强1.69)

我有一个结构

#include <string>
#include <cstdint>
namespace rtsp {
    struct request {
    };
    struct response {
        uint_fast16_t rtsp_version_major;
        uint_fast16_t rtsp_version_minor;
        uint_fast16_t status_code;
        std::string reason_phrase;
    };
    using message = boost::variant<request, response>;
}

我可以通过

boost::spirit::qi一起使用
BOOST_FUSION_ADAPT_STRUCT(
        rtsp::response,
        (uint_fast16_t, rtsp_version_major)
        (uint_fast16_t, rtsp_version_minor)
        (uint_fast16_t, status_code)
        (std::string, reason_phrase)

但是由于我现在还想使用boost :: spirit :: karma生成并且不仅解析结构,所以我必须使用

BOOST_FUSION_ADAPT_ADT(
        rtsp::response,
(uint_fast16_t,const uint_fast16_t&,obj.rtsp_version_major, obj.rtsp_version_major = val)
(uint_fast16_t,const uint_fast16_t&,obj.rtsp_version_minor, obj.rtsp_version_minor = val)
(uint_fast16_t,const uint_fast16_t&,obj.status_code, obj.status_code = val)
(std::string,const std::string&,obj.reason_phrase, obj.reason_phrase = val)
)

但是它会爆炸,从模板错误到语法错误(例如

  

包含在以下文件中   /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:11:   在包含的文件中   /Users/markus/include/boost/spirit/include/qi.hpp:16:包含在文件中   来自/Users/markus/include/boost/spirit/home/qi.hpp:14:在文件中   来自   /Users/markus/include/boost/spirit/home/qi/action.hpp:14:在文件中   来自   /Users/markus/include/boost/spirit/home/qi/action/action.hpp:16:   /Users/markus/include/boost/spirit/home/qi/detail/attributes.hpp:153:9:   错误:的模棱两可的局部专业化   'transform_attribute,unsigned short,boost :: spirit :: qi :: domain,void>'         :transform_attribute

由于它已经在#include <boost/spirit/include/qi.hpp>行中失败了,也许有人知道如何更正BOOST_FUSION_ADAPT_ADT这个短语?


整个代码:     / *! @file rtsp_request.hpp      *      * /

#ifndef RTSP_GUI_RTSP_PARSER_HPP
#define RTSP_GUI_RTSP_PARSER_HPP

#include <string>
#include <cstdint>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/fusion/adapted/adt/adapt_adt.hpp>
#include <boost/spirit/include/support_adapt_adt_attributes.hpp>



namespace rtsp {
    struct request {
    };
    struct response {
        uint_fast16_t rtsp_version_major;
        uint_fast16_t rtsp_version_minor;
        uint_fast16_t status_code;
        std::string reason_phrase;
    };
    using message = boost::variant<request, response>;
}
BOOST_FUSION_ADAPT_ADT(
        rtsp::response,
(uint_fast16_t,const uint_fast16_t&,obj.rtsp_version_major, obj.rtsp_version_major = val)
(uint_fast16_t,const uint_fast16_t&,obj.rtsp_version_minor, obj.rtsp_version_minor = val)
(uint_fast16_t,const uint_fast16_t&,obj.status_code, obj.status_code = val)
(std::string,const std::string&,obj.reason_phrase, obj.reason_phrase = val)
)
/*
BOOST_FUSION_ADAPT_STRUCT(
        rtsp::response,
        (uint_fast16_t, rtsp_version_major)
        (uint_fast16_t, rtsp_version_minor)
        (uint_fast16_t, status_code)
        (std::string, reason_phrase)
)*/
namespace rtsp {

    template<typename Iterator>
    struct rtsp_response_grammar
            : ::boost::spirit::qi::grammar<Iterator, response()> {
        rtsp_response_grammar() : rtsp_response_grammar::base_type(start) {
            namespace ns = ::boost::spirit::standard;
            using ::boost::spirit::qi::uint_parser;
            using ::boost::spirit::qi::lexeme;
            using ::boost::spirit::qi::lit;
            using boost::spirit::qi::omit;
            using ::boost::spirit::qi::repeat;
            quoted_string %= lexeme['"' >> +(ns::char_ - '"') >> '"'];
            status_code = uint_parser<uint_fast16_t, 10, 3, 3>();
            at_least_one_digit = uint_parser<uint_fast16_t, 10, 1>();

            start %= lit("RTSP/") >> at_least_one_digit >> "." >> at_least_one_digit >> omit[+ns::space]
                    >> status_code >> omit[+ns::space]
                    >> *(ns::char_ - (lit("\r") | lit("\n")))
                    >> lit("\r\n");
        }

        boost::spirit::qi::rule<Iterator, std::string()> quoted_string;
        boost::spirit::qi::rule<Iterator, uint_fast16_t()> status_code;
        boost::spirit::qi::rule<Iterator, uint_fast16_t()> at_least_one_digit;
        boost::spirit::qi::rule<Iterator, response()> start;

    };

    template <typename OutputIterator>
    bool generate_response(OutputIterator sink, const response& reponse)
    {
        using ::boost::spirit::karma::lit;

        return boost::spirit::karma::generate(sink, lit("RTSP/"), reponse);
    }
}


#endif //RTSP_GUI_RTSP_PARSER_HPP
/*! @file rtsp_request.cpp
 *
 */

#include "rtsp_request.hpp"

#include <iterator>

template
struct rtsp::rtsp_response_grammar<std::string::const_iterator>;

template
bool rtsp::generate_response<std::back_insert_iterator<std::string>>(std::back_insert_iterator<std::string> sink, const response& reponse);

顺便说一句,尝试仅将BOOST_FUSION_ADAPT_STRUCT与业力生成器函数一起使用也会失败:

  

包含在以下文件中   /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/src/rtsp_request.cpp:5:   在包含的文件中   /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:11:   在包含的文件中   /Users/markus/include/boost/spirit/include/qi.hpp:16:包含在文件中   来自/Users/markus/include/boost/spirit/home/qi.hpp:14:在文件中   来自   /Users/markus/include/boost/spirit/home/qi/action.hpp:14:在文件中   来自   /Users/markus/include/boost/spirit/home/qi/action/action.hpp:14:在   来自的文件   /Users/markus/include/boost/spirit/home/qi/meta_compiler.hpp:15:在   来自的文件   /Users/markus/include/boost/spirit/home/qi/domain.hpp:18:在文件中   来自   /Users/markus/include/boost/spirit/home/support/context.hpp:18:在   来自的文件   /Users/markus/include/boost/spirit/home/support/nonterminal/expand_arg.hpp:20:   /Users/markus/include/boost/spirit/home/support/string_traits.hpp:156:26:   错误:未定义模板的隐式实例化   'boost :: spirit :: traits :: char_type_of'           typedef typename char_type_of :: type char_type;                            ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:242:14:   注意:在模板类的实例化中   要求'boost :: spirit :: traits :: extract_c_string'   这里       类型名称extract_c_string :: char_type const *                ^ /Users/markus/include/boost/spirit/home/karma/string/lit.hpp:180:21:   注意:在将推导的模板参数替换为函数时   模板“ get_c_string” [with String = rtsp :: response]                       get_c_string(                       ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:69:45:   注意:在功能模板专门化的实例中   'boost :: spirit :: karma :: literal_string :: generate

     
    

,mpl _ :: int_ <0>,boost :: spirit :: unused_type>,boost :: spirit :: context,boost :: spirit :: locals>,boost :: spirit :: unused_type,rtsp :: response >'已要求     这里             返回compile(expr).generate(接收器,上下文,未使用,attr);                                                 ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:91:23:     注意:在功能模板专门化的实例中     'boost :: spirit :: karma :: generate     ,mpl _ :: int_ <0>,boost :: proto :: exprns _ :: expr>>,0>,rtsp :: response>'     在这里要求             返回业力::生成(接收器,expr,attr);                           ^ /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:69:38:     注意:在功能模板专门化的实例中     'boost :: spirit :: karma :: generate     ,boost :: proto :: exprns _ :: expr>>,0>,rtsp :: response>'     在这里要求             return boost :: spirit :: karma :: generate(sink,lit(“ RTSP /”),reponse);                                          ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:96:12:     注意:模板在这里声明         struct char_type_of;                ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:179:20:     错误:没有匹配功能可调用“通话”                 返回extract_c_string :: call(str);                        ^ ~~~~~~~~~~~~~~~~~~~~~~~ / Users / markus / include / boost / spirit / home / support / string_traits.hpp:238:42:     注意:在实例化成员函数时     'boost :: spirit :: traits :: extract_c_string :: call'     在这里要求             返回extract_c_string :: call(str);                                              ^ /Users/markus/include/boost/spirit/home/karma/string/lit.hpp:180:21:     注意:在功能模板专门化的实例中     要求'boost :: spirit :: traits :: get_c_string'     这里                         get_c_string(                         ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:69:45:     注意:在功能模板专门化的实例中     'boost :: spirit :: karma :: literal_string :: generate     ,mpl _ :: int_ <0>,boost :: spirit :: unused_type>,boost :: spirit :: context,boost :: spirit :: locals>,boost :: spirit :: unused_type,rtsp :: response>     这里             返回compile(expr).generate(接收器,上下文,未使用,attr);                                                 ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:91:23:     注意:在功能模板专门化的实例中     'boost :: spirit :: karma :: generate     ,mpl _ :: int_ <0>,boost :: proto :: exprns _ :: expr>>,0>,rtsp :: response>'     在这里要求             返回业力::生成(接收器,expr,attr);                           ^ /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:69:38:     注意:在功能模板专门化的实例中     'boost :: spirit :: karma :: generate     ,boost :: proto :: exprns _ :: expr>>,0>,rtsp :: response>'     在这里要求             return boost :: spirit :: karma :: generate(sink,lit(“ RTSP /”),reponse);                                          ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:159:25:     注意:候选模板被忽略:无法将'T '与     'rtsp ::响应'             静态T const 调用(T * str)                             ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:165:25:     注意:候选模板被忽略:无法将'const T '与     'rtsp ::响应'             静态T const 调用(T const * str)

  

1 个答案:

答案 0 :(得分:2)

定义明确的语法可以毫无问题地处理BOOST_FUSION_ADAPT_STRUCTBOOST_FUSION_ADAPT_ADT

示例:

namespace rtsp {
    ...

    template <typename OutputIterator>
    bool generate_response(OutputIterator sink, const response& reponse)
    {
        using ::boost::spirit::karma::lit;
        using ::boost::spirit::karma::uint_;
        using ::boost::spirit::karma::string;

        return boost::spirit::karma::generate(sink,
            lit("RTSP/") << uint_ << "." << uint_ << " " << uint_ << " " << string
          , reponse);
    }
}

int main()
{
    std::string s;
    generate_response(std::back_inserter(s), rtsp::response{ 1, 0, 200, "OK" });
    std::cout << s;
}

打印:RTSP/1.0 200 OK

更新:涉及BOOST_FUSION_ADAPT_ADT confirmed and reported的Qi错误。

相关问题