【发布时间】:2018-05-12 19:34:48
【问题描述】:
在 Stackoverflow 有几个与使用 {boost, std}::string_view 相关的问答,例如:
-
parsing from std::string into a boost::string_view using boost::spirit::x3 重载 x3 的
move_tonamespace boost { namespace spirit { namespace x3 { namespace traits { template <typename It> void move_to(It b, It e, boost::string_view& v) { v = boost::string_view(&*b, e-b); } } } } } -
parse into vector using boost::spirit::x3,其中进一步提供了有关属性兼容性的信息
namespace boost { namespace spirit { namespace x3 { namespace traits { template <> struct is_substitute<raw_attribute_type,boost::string_view> : boost::mpl::true_ {}; } } } }
llonesmiz 在wandbox 写了一个示例,它使用boost 1.64 编译,但现在使用boost 1.67 失败了
opt/wandbox/boost-1.67.0/gcc-7.3.0/include/boost/spirit/home/x3/support/traits/container_traits.hpp:177:15: error: 'class boost::basic_string_view<char, std::char_traits<char> >' has no member named 'insert'
c.insert(c.end(), first, last);
~~^~~~~~
我在项目中遇到的同样错误。
使用std::string 也会引发问题
即使明确使用了Sehe's as<> "directive",也请参见wandbox:
#include <iostream>
#include <string>
#include <string_view>
namespace boost { namespace spirit { namespace x3 { namespace traits {
template <typename It>
void move_to(It b, It e, std::string_view& v)
{
v = std::string_view(&*b, e-b);
}
} } } } // namespace boost
#include <boost/spirit/home/x3.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits {
template <>
struct is_substitute<raw_attribute_type, std::string_view> : boost::mpl::true_
{};
} } } } // namespace boost
namespace parser
{
namespace x3 = boost::spirit::x3;
using x3::char_;
using x3::raw;
template<typename T>
auto as = [](auto p) { return x3::rule<struct _, T>{ "as" } = x3::as_parser(p); };
const auto str = as<std::string_view>(raw[ +~char_('_')] >> '_');
const auto str_vec = *str;
}
int main()
{
std::string input = "hello_world_";
std::vector<std::string_view> strVec;
boost::spirit::x3::parse(input.data(), input.data()+input.size(), parser::str_vec, strVec);
for(auto& x : strVec) { std::cout << x << std::endl; }
}
据我所知,问题始于 boost 1.65。发生了什么变化以及如何解决?
最后,我有一个关于sehe提到的连续存储要求的问题:我理解这个要求,但是解析器可以违反这个吗? - 在我看来,解析器即使在回溯时也必须失败,所以这不可能发生在精神上。通过使用error_handler,引用string_view的内存存储地址最终在解析级别有效。我的结论是,在这种情况下,只要引用在范围内,使用 string_view 就可以保存,不是吗?
【问题讨论】:
标签: c++ boost boost-spirit-x3