Boost::qi解析HLS的#EXTINF标签时ref调用歧义编译错误求解
问题分析
- 编译报错的核心原因是
ref没有指定命名空间:Boost.Spirit的语义动作需要使用boost::phoenix::ref包装变量才能和占位符_1配合,而标准库也存在std::ref模板,二者都支持接收std::string&类型参数,编译器无法判断你要调用的实现,因此触发重载歧义错误。 - 代码存在隐藏逻辑问题:你定义的
quoutedString规则使用+(char_)会匹配所有剩余的输入字符,包括换行符,不符合HLS标签单行的格式要求,会导致后续first != last的校验失败,即使字段匹配正确也会返回解析错误。
解决方案
按如下步骤修改即可解决问题:
- 显式指定语义动作中使用的引用包装器为
boost::phoenix::ref,消除命名空间冲突 - 修正字符串匹配规则,限制仅匹配非换行符,避免越界匹配标签外的内容
- 解析前提前清空
title变量,避免未匹配到标题字段时残留旧值
修正后的代码示例:
double duration; std::string title; title.clear(); boost::spirit::qi::rule<Iterator, std::string()> titleRule; titleRule %= boost::spirit::qi::lexeme[+(boost::spirit::qi::char_ - '\n')]; bool r = boost::spirit::qi::parse(first, last, ("#EXTINF:" >> boost::spirit::qi::double_[boost::phoenix::ref(duration) = boost::spirit::qi::_1] >> -(',' >> titleRule[boost::phoenix::ref(title) = boost::spirit::qi::_1] ) ) ); if (!r || first != last) { addMinorProblem(stateObj, _("Cannot parse information from #EXTINF tag")); return false; }
修改后可以完美适配你的三个测试场景:
- 输入
#EXTINF:10,Title of the segment:提取到title为"Title of the segment" - 输入
#EXTINF:20,Title:提取到title为"Title" - 输入
#EXTINF:12:title保持为空字符串
内容的提问来源于stack exchange,提问作者Валентин Никин
相关产品推荐
相关产品推荐

