1

我不确定这是否与使用 BOOST_FUSION_ADAPT_ADT 适应类时出现错误有关,但即使是这样,其背后的问题仍然没有得到回答/仍然失败,请参阅作者在使用 BOOST_FUSION_ADAPT_ADT 适应类时出错的评论。(我使用了 boost 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::qivia

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短语?


整个代码:/*!@文件 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/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::

, mpl_::int_<0>, boost::spirit::unused_type>, boost::spirit::context, boost::spirit::locals >, boost::spirit::unused_type, rtsp::response>' 请求这里返回 compile(expr).generate(sink, context, used, 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>' 在此请求 return karma::generate(sink, 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:错误:没有匹配函数调用'call'返回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>' 这里请求返回编译( expr).generate(sink, context, 未使用, 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>' 在此请求 return karma::generate(sink, 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);'反对'rtsp::response'静态T const调用(T* str)^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:165:25:注意:候选模板被忽略:无法匹配'const T ' 反对 'rtsp::response' 静态 T const调用 (T const* str)

4

1 回答 1

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

更新:涉及Qi bug的BOOST_FUSION_ADAPT_ADT 确认并报告

于 2018-09-07T15:43:41.600 回答