在 Rust 中,我可以写(Rust Playground):
let vec = "Hello-+-Rust-+-!".split("-+-").collect::<Vec<_>>();
println!("{:?}", vec); // ["Hello", "Rust", "!"]
我想在 C++23 中做同样的事情。
我写了(编译器资源管理器):
#include <ranges>
#include <vector>
#include <print>
int main()
{
auto vec = "Hello-+-C++-+-23-+-!"
| std::ranges::views::lazy_split(std::string_view("-+-"))
| std::ranges::to<std::vector<std::string_view>>();
std::println("{}", vec);
}
但是 clang 报了 2 个错误:
In file included from <source>:1:
In file included from /opt/compiler-explorer/clang-trunk-20240518/bin/../include/c++/v1/ranges:416:
/opt/compiler-explorer/clang-trunk-20240518/bin/../include/c++/v1/__ranges/to.h:134:18: error: no matching function for call to 'to'
134 | return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
/opt/compiler-explorer/clang-trunk-20240518/bin/../include/c++/v1/__ranges/to.h:133:27: error: invalid operands to binary expression ('ref_view<lazy_split_view<ref_view<const char[21]>, string_view>>' (aka 'ref_view<std::ranges::lazy_split_view<std::ranges::ref_view<const char[21]>, std::string_view>>') and '__range_adaptor_closure_t<__bind_back_t<__fn, tuple<(lambda at /opt/compiler-explorer/clang-trunk-20240518/bin/../include/c++/v1/__ranges/to.h:133:46)>>>' (aka 'std::ranges::__range_adaptor_closure_t<std::__bind_back_t<std::ranges::views::__transform::__fn, std::tuple<(lambda at /opt/compiler-explorer/clang-trunk-20240518/bin/../include/c++/v1/__ranges/to.h:133:46)>>>'))
133 | ref_view(__range) | views::transform([](auto&& __elem) {
| ~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
134 | return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135 | }),
| ~~
...
2 errors generated.
ASM generation compiler returned: 1
我怎么知道哪里出了问题?
views::lazy_split
是lazy,这意味着分割子范围最多只能满足forward_range
,你应该使用views::split
auto vec = "Hello-+-C++-+-23-+-!"
| std::ranges::views::split(std::string_view("-+-"))
| std::views::transform([](auto r) { return std::string_view{r}; })
| std::ranges::to<std::vector>();
std::println("{}", vec);