【发布时间】:2022-07-06 17:39:36
【问题描述】:
我正在尝试使用 ranges-v3 将 SNMP OID 拆分为多个部分并将它们作为std::deque<uint32_t> 返回。
以下代码有效,但只有在我添加了一些额外的非自然步骤之后:
#include <range/v3/all.hpp>
/// split the supplied string into nodes, using '.' as a delimiter
/// @param the path to split , e.g "888.1.2.3.4"
/// @return a std::deque<uint32_t> containing the split paths
static std::deque<uint32_t> splitPath(std::string_view path) {
constexpr std::string_view delim{"."};
auto tmp = path | ranges::views::split(delim)
| ranges::to<std::vector<std::string>>()
;
return tmp | ranges::views::transform([](std::string_view v) {
return std::stoul(std::string{v}); })
| ranges::to<std::deque<uint32_t>>();
}
最初我希望以下内容能够简单地工作:
static std::deque<uint32_t> splitPath(std::string_view path) {
constexpr std::string_view delim{"."};
return path | ranges::views::split(delim)
| ranges::views::transform([](std::string_view v) {
return std::stoul(std::string{v}); })
| ranges::to<std::deque<uint32_t>>();
}
但这会导致以下错误:
error: no match for ‘operator|’ (operand types are
‘ranges::split_view<std::basic_string_view<char>,
std::basic_string_view<char> >’ and
‘ranges::views::view_closure<ranges::detail::
bind_back_fn_<ranges::views::transform_base_fn, ahk::snmp::
{anonymous}::splitPath(std::string_view)::<lambda(std::string_view)> > >’)
36 | return path | ranges::views::split(delim)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| ranges::split_view<std::basic_string_view<char>,
std::basic_string_view<char> >
37 | | ranges::views::transform([](std::string_view v) {
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| ranges::views::view_closure<ranges::detail::bind_back_fn_
<ranges::views::transform_base_fn, ahk::snmp::
{anonymous}::splitPath(std::string_view)::<lambda(std::string_view)> > >
38 | return std::stoul(std::string{v}); })
为什么在调用ranges::views::transform之前必须将第一个操作的结果转换为std::vector并存储在命名值(tmp)中?即使是以下代码(删除命名值 tmp 也会失败:
static std::deque<uint32_t> splitPath(std::string_view path) {
constexpr std::string_view delim{"."};
return path | ranges::views::split(delim)
| ranges::to<std::vector<std::string>>()
| ranges::views::transform([](std::string_view v) {
return std::stoul(std::string{v}); })
| ranges::to<std::deque<uint32_t>>();
}
【问题讨论】: