【发布时间】:2018-05-27 06:42:31
【问题描述】:
我想写一个简单的字符串split函数。
该函数应采用一个std::basic_string 和一个分隔符(可能是CharT 或std::basic_string),并将结果放入ContainerT。
我的第一次尝试是
template <typename StringT, typename DelimiterT, typename ContainerT>
void split(
const StringT &str, const DelimiterT &delimiters, ContainerT &conts) {
conts.clear();
std::size_t start = 0, end;
std::size_t len = delimiters.size();
while ((end = str.find(delimiters, start)) != StringT::npos) {
if (end - start) {
conts.emplace_back(str, start, end - start);
}
start = end + len;
}
if (start != StringT::npos && start < str.size()) {
conts.emplace_back(str, start, str.size() - start);
}
}
我的最终目标是扩展这个功能来实现:
- 最终结果总是
std::basic_string<CharT>放入一些conts。 - 第一个参数
str可以是std::basic_string<CharT>、const CharT*或字符串文字。 - 第二个参数
delimiter可以是char,也可以是std::basic_string<CharT>/const CharT*/字符串字面量,表示分隔符的长度大于1,例如将aaa,,bbb,c与,,分开得到aaa/bbb,c。 - 第三个参数可以是来自
STL的任何序列容器。
由于 1 通常处理 C++ 中的现代字符串,因此 2 可能是 std::basic_string<CharT> 只是为了简化。
鉴于函数(模板)可以重载,我想知道
- 在这种情况下我至少需要多少个函数?
- 设计此类函数的最佳实践是什么(如何编写更通用的函数)?例如,也许要使上述函数与
const CharT*分隔符一起工作,必须将std::size_t len = delimiters.size();行更改为std::distance(...)?
更新:
添加了一个相似的代码审查here。
【问题讨论】:
-
我觉得这很棘手,因为所有潜在的组合。我尝试了很多方法。我目前使用的有一个 master 模板函数,它只为输入字符串和定界符(四个迭代器 s_begin、s_end、d_begin、d_end)采用迭代器。然后我有很多不同的重载将它们的输入参数转换为最基本的形式。
-
你看到stackoverflow.com/questions/236129/…的顶级答案了吗