**一、std::views::split**
**功能**
将一个范围(如字符串)按指定分隔符分割为多个子范围。
**基本用法**
cpp
#include <iostream>
#include <ranges>
#include <string>
int main() {
std::string text = "hello,world,example";
auto words = text | std::views::split(',');
for (auto word : words) {
// word 是一个字符子范围,转换为 string 输出
std::cout << std::string(word.begin(), word.end()) << '\n';
}
// 输出:
// hello
// world
// example
}
**技术细节**
1. **分隔符类型**:
- 单个字符:如 `','`
- 字符范围:如 `std::string("-,")`
```cpp
std::string text = "a-b,c";
auto parts = text | std::views::split(std::string_view("-,"));
// 分割为 {"a", "b", "c"}
```
2. **空字符串处理**:
- 连续分隔符会产生空字符串。
```cpp
std::string text = "a,,b";
auto parts = text | std::views::split(',');
// 分割为 {"a", "", "b"}
```
3. **惰性计算**:
- 不立即生成所有子字符串,而是在迭代时按需计算。
**二、std::views::join**
**功能**
将多个范围连接为一个单一范围。
**基本用法**
cpp
#include <iostream>
#include <ranges>
#include <vector>
#include <string>
int main() {
std::vector<std::string> words = {"hello", "world", "!"};
auto joined = words | std::views::join;
// 输出连接后的字符范围
for (char c : joined) {
std::cout << c;
}
// 输出: helloworld!
}
**结合分隔符使用**
若需在元素间添加分隔符,可配合 `std::views::transform` 和 `std::views::join`:
cpp
std::vector<std::string> words = {"hello", "world", "!"};
auto with_space = words | std::views::transform([](const auto& s) {
return std::views::concat(s, std::views::single(' '));
});
auto joined = with_space | std::views::join;
// 输出: hello world !
**技术细节**
1. **输入要求**:
- 必须是范围的范围(如 `vector<string>`)。
- 若直接对字符串使用 `join` 会报错,需先包装为范围:
```cpp
std::string s = "abc";
auto wrapped = std::views::single(s);
auto joined = wrapped | std::views::join; // 正确
```
2. **惰性计算**:
- 与 `split` 类似,仅在迭代时生成结果。
**三、组合使用**
分割后再连接:
cpp
std::string text = "a,b,c";
auto split_view = text | std::views::split(',');
auto joined_view = split_view | std::views::join;
// 将 joined_view 转换为字符串
std::string result(joined_view.begin(), joined_view.end());
// result = "abc"
**四、注意事项**
1. **临时对象生命周期**:
```cpp
// 错误:临时字符串在 split 操作前已销毁
auto parts = std::string("a,b,c") | std::views::split(',');
// 正确:延长临时对象生命周期
auto parts = std::views::owning_view(std::string("a,b,c")) | std::views::split(',');
```
2. **空范围处理**:
- 空输入会生成空输出,不会导致异常。
3. **性能优势**:
- 避免了中间容器的内存分配,适合处理大型数据。
**五、与传统方法对比**
| 操作 | 传统方法 | 范围适配器方法 |
|---------------|------------------------------|--------------------------------|
| 字符串分割 | `std::stringstream` + getline| `std::views::split` |
| 字符串连接 | `std::string::append` | `std::views::join` |
| 临时容器 | 需要(如 `vector<string>`) | 不需要(惰性计算) |
| 代码复杂度 | 较高 | 较低(链式调用) |
**总结**
- **`std::views::split`**:用于字符串分割,支持惰性计算,返回子范围视图。
- **`std::views::join`**:用于范围连接,同样支持惰性计算,避免临时容器。
- **适用场景**:处理大型文本、数据流或需要高效内存使用的场景。