如何用std::ranges::split_view打印拆分后的单词?技术咨询
如何直接打印std::ranges::split_view拆分后的单词?
你遇到的问题并不是std::ranges::single_view<char>的限制,而是因为split_view拆分后得到的每个"单词"是视图类型(具体是std::ranges::subrange,本质是一对迭代器,指向原字符串的一段区间),而标准库的std::ostream并没有为这类字符视图提供默认的operator<<重载,所以直接打印会触发编译错误。
要直接打印拆分后的单词,有几种可行的方案:
1. 将视图转换为std::string
最简单的方法是把每个子范围视图转换成std::string,因为std::string有现成的operator<<支持。利用std::string的迭代器构造函数就能快速完成转换:
#include <iostream> #include <ranges> #include <string> int main() { std::string str{"the quick brown fox"}; std::ranges::split_view sentence{str, ' '}; for (auto word : sentence) { // 将子范围视图转换为string后打印 std::cout << std::string(word.begin(), word.end()) << "*"; } return 0; }
这个代码会输出预期结果:the*quick*brown*fox*
2. 自定义operator<<重载
如果需要频繁打印这类字符子范围,可以自己为std::ranges::subrange(或者更通用的字符视图)定义operator<<,这样以后就能直接像打印string一样打印视图:
#include <iostream> #include <ranges> #include <string> #include <iterator> // 为字符类型的子范围视图重载<< template <std::input_iterator It, std::sentinel_for<It> S> std::ostream& operator<<(std::ostream& os, const std::ranges::subrange<It, S>& r) { std::ranges::copy(r, std::ostream_iterator<char>(os)); return os; } int main() { std::string str{"the quick brown fox"}; std::ranges::split_view sentence{str, ' '}; for (auto word : sentence) { // 现在可以直接打印word了 std::cout << word << "*"; } return 0; }
3. 使用std::ranges::copy输出
也可以直接用std::ranges::copy把视图的内容复制到输出流迭代器,效果和转换string类似:
#include <iostream> #include <ranges> #include <string> #include <iterator> int main() { std::string str{"the quick brown fox"}; std::ranges::split_view sentence{str, ' '}; for (auto word : sentence) { std::ranges::copy(word, std::ostream_iterator<char>(std::cout)); std::cout << "*"; } return 0; }
总结一下:split_view返回的子范围是视图而非容器,标准库没有默认支持直接输出,所以需要我们手动转换或自定义重载来实现直接打印的需求,和分隔符的类型(单个元素或视图)无关。
内容的提问来源于stack exchange,提问作者Tony Tannous
相关产品推荐
相关产品推荐

