BOOST_FUSION_ADAPT_ADT 与 boost::karma 一起使用时爆炸
BOOST_FUSION_ADAPT_ADT explodes when using with boost::karma
我不确定这是否与 ,but even if it is, the question behind it is still not answered/still fails see the comment of the author 有关。 (我用的是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::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)
)
但它会出现一些错误,从模板错误到语法错误,例如
In file included from
/Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:11:
In file included from
/Users/markus/include/boost/spirit/include/qi.hpp:16: In file included
from /Users/markus/include/boost/spirit/home/qi.hpp:14: In file
included from
/Users/markus/include/boost/spirit/home/qi/action.hpp:14: In file
included from
/Users/markus/include/boost/spirit/home/qi/action/action.hpp:16:
/Users/markus/include/boost/spirit/home/qi/detail/attributes.hpp:153:9:
error: ambiguous partial specializations of
'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 与业力生成器函数一起使用也会失败:
In file included from
/Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/src/rtsp_request.cpp:5:
In file included from
/Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:11:
In file included from
/Users/markus/include/boost/spirit/include/qi.hpp:16: In file included
from /Users/markus/include/boost/spirit/home/qi.hpp:14: In file
included from
/Users/markus/include/boost/spirit/home/qi/action.hpp:14: In file
included from
/Users/markus/include/boost/spirit/home/qi/action/action.hpp:14: In
file included from
/Users/markus/include/boost/spirit/home/qi/meta_compiler.hpp:15: In
file included from
/Users/markus/include/boost/spirit/home/qi/domain.hpp:18: In file
included from
/Users/markus/include/boost/spirit/home/support/context.hpp:18: In
file included from
/Users/markus/include/boost/spirit/home/support/nonterminal/expand_arg.hpp:20:
/Users/markus/include/boost/spirit/home/support/string_traits.hpp:156:26:
error: implicit instantiation of undefined template
'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:
note: in instantiation of template class
'boost::spirit::traits::extract_c_string' requested
here
typename extract_c_string::char_type const*
^ /Users/markus/include/boost/spirit/home/karma/string/lit.hpp:180:21:
note: while substituting deduced template arguments into function
template 'get_c_string' [with String = rtsp::response]
get_c_string(
^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:69:45:
note: in instantiation of function template specialization
'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>' requested
here
return compile(expr).generate(sink, context, unused, attr);
^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:91:23:
note: in instantiation of function template specialization
'boost::spirit::karma::generate
, mpl_::int_<0>, boost::proto::exprns_::expr > >, 0>, rtsp::response>'
requested here
return karma::generate(sink, expr, attr);
^ /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:69:38:
note: in instantiation of function template specialization
'boost::spirit::karma::generate
, boost::proto::exprns_::expr > >, 0>, rtsp::response>'
requested here
return boost::spirit::karma::generate(sink, lit("RTSP/"), reponse);
^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:96:12:
note: template is declared here
struct char_type_of;
^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:179:20:
error: no matching function for call to 'call'
return extract_c_string::call(str);
^~~~~~~~~~~~~~~~~~~~~~~~~ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:238:42:
note: in instantiation of member function
'boost::spirit::traits::extract_c_string::call'
requested here
return extract_c_string::call(str);
^ /Users/markus/include/boost/spirit/home/karma/string/lit.hpp:180:21:
note: in instantiation of function template specialization
'boost::spirit::traits::get_c_string' requested
here
get_c_string(
^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:69:45:
note: in instantiation of function template specialization
'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>' requested
here
return compile(expr).generate(sink, context, unused, attr);
^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:91:23:
note: in instantiation of function template specialization
'boost::spirit::karma::generate
, mpl_::int_<0>, boost::proto::exprns_::expr > >, 0>, rtsp::response>'
requested here
return karma::generate(sink, expr, attr);
^ /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:69:38:
note: in instantiation of function template specialization
'boost::spirit::karma::generate
, boost::proto::exprns_::expr > >, 0>, rtsp::response>'
requested here
return boost::spirit::karma::generate(sink, lit("RTSP/"), reponse);
^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:159:25:
note: candidate template ignored: could not match 'T ' against
'rtsp::response'
static T const call (T* str)
^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:165:25:
note: candidate template ignored: could not match 'const T ' against
'rtsp::response'
static T const call (T const* str)
定义良好的语法可以毫无问题地处理 BOOST_FUSION_ADAPT_STRUCT
或 BOOST_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 错误
我不确定这是否与
我有一个结构
#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)
)
但它会出现一些错误,从模板错误到语法错误,例如
In file included from /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:11: In file included from /Users/markus/include/boost/spirit/include/qi.hpp:16: In file included from /Users/markus/include/boost/spirit/home/qi.hpp:14: In file included from /Users/markus/include/boost/spirit/home/qi/action.hpp:14: In file included from /Users/markus/include/boost/spirit/home/qi/action/action.hpp:16: /Users/markus/include/boost/spirit/home/qi/detail/attributes.hpp:153:9: error: ambiguous partial specializations of '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 与业力生成器函数一起使用也会失败:
In file included from /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/src/rtsp_request.cpp:5: In file included from /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:11: In file included from /Users/markus/include/boost/spirit/include/qi.hpp:16: In file included from /Users/markus/include/boost/spirit/home/qi.hpp:14: In file included from /Users/markus/include/boost/spirit/home/qi/action.hpp:14: In file included from /Users/markus/include/boost/spirit/home/qi/action/action.hpp:14: In file included from /Users/markus/include/boost/spirit/home/qi/meta_compiler.hpp:15: In file included from /Users/markus/include/boost/spirit/home/qi/domain.hpp:18: In file included from /Users/markus/include/boost/spirit/home/support/context.hpp:18: In file included from /Users/markus/include/boost/spirit/home/support/nonterminal/expand_arg.hpp:20: /Users/markus/include/boost/spirit/home/support/string_traits.hpp:156:26: error: implicit instantiation of undefined template '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: note: in instantiation of template class 'boost::spirit::traits::extract_c_string' requested here typename extract_c_string::char_type const* ^ /Users/markus/include/boost/spirit/home/karma/string/lit.hpp:180:21: note: while substituting deduced template arguments into function template 'get_c_string' [with String = rtsp::response] get_c_string( ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:69:45: note: in instantiation of function template specialization '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>' requested here return compile(expr).generate(sink, context, unused, attr); ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:91:23: note: in instantiation of function template specialization 'boost::spirit::karma::generate , mpl_::int_<0>, boost::proto::exprns_::expr > >, 0>, rtsp::response>' requested here return karma::generate(sink, expr, attr); ^ /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:69:38: note: in instantiation of function template specialization 'boost::spirit::karma::generate , boost::proto::exprns_::expr > >, 0>, rtsp::response>' requested here return boost::spirit::karma::generate(sink, lit("RTSP/"), reponse); ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:96:12: note: template is declared here struct char_type_of; ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:179:20: error: no matching function for call to 'call' return extract_c_string::call(str); ^~~~~~~~~~~~~~~~~~~~~~~~~ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:238:42: note: in instantiation of member function 'boost::spirit::traits::extract_c_string::call' requested here return extract_c_string::call(str); ^ /Users/markus/include/boost/spirit/home/karma/string/lit.hpp:180:21: note: in instantiation of function template specialization 'boost::spirit::traits::get_c_string' requested here get_c_string( ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:69:45: note: in instantiation of function template specialization '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>' requested here return compile(expr).generate(sink, context, unused, attr); ^ /Users/markus/include/boost/spirit/home/karma/generate.hpp:91:23: note: in instantiation of function template specialization 'boost::spirit::karma::generate , mpl_::int_<0>, boost::proto::exprns_::expr > >, 0>, rtsp::response>' requested here return karma::generate(sink, expr, attr); ^ /Users/markus/Entwicklung/HTW/RTSP-Streaming/src/streaming_lib/include/rtsp_request.hpp:69:38: note: in instantiation of function template specialization 'boost::spirit::karma::generate , boost::proto::exprns_::expr > >, 0>, rtsp::response>' requested here return boost::spirit::karma::generate(sink, lit("RTSP/"), reponse); ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:159:25: note: candidate template ignored: could not match 'T ' against 'rtsp::response' static T const call (T* str) ^ /Users/markus/include/boost/spirit/home/support/string_traits.hpp:165:25: note: candidate template ignored: could not match 'const T ' against 'rtsp::response' static T const call (T const* str)
定义良好的语法可以毫无问题地处理 BOOST_FUSION_ADAPT_STRUCT
或 BOOST_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.