我试图将此函数转换为模板:
std::vector<std::string> StrSplit(const std::string& i_str, const std::string& i_delim)
{
std::vector<std::string> result;
size_t found = i_str.find(i_delim);
size_t startIndex = 0;
while (found != std::string::npos)
{
result.emplace_back(std::string(i_str.begin() + startIndex, i_str.begin() + found));
startIndex = found + i_delim.size();
found = i_str.find(i_delim, startIndex);
}
if (startIndex != i_str.size())
result.emplace_back(std::string(i_str.begin() + startIndex, i_str.end()));
return result;
}目标是让它支持我尝试过的string和wstring:
template <typename T, typename T2>
std::vector<T> StrSplit(T& i_str, T2& i_delim)
{
std::vector<T> result;
size_t found = i_str.find(i_delim);
size_t startIndex = 0;
while (found != T::npos)
{
result.emplace_back(T(i_str.begin() + startIndex, i_str.begin() + found));
startIndex = found + i_delim.size();
found = i_str.find(i_delim, startIndex);
}
if (startIndex != i_str.size())
result.emplace_back(T(i_str.begin() + startIndex, i_str.end()));
return result;
}我得到了一个错误:binary '=': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion)
我对模板知之甚少,这条错误信息也没有多大帮助。
发布于 2022-08-28 05:58:54
您似乎对T是std::string还是std::vector<std::string>感到有点困惑。您的一些代码将其视为第一个代码,一些代码将其视为第二个代码。
这是我的努力。我保留了const (为什么要删除这些),并且只有一个模板参数,因为我看不出您希望在一个函数调用中混合不同的字符串类型。
我还删除了显式的T构造函数调用。在此代码中或在原始代码中使用emplace_back时,这是不必要的。
template <typename T>
std::vector<T> StrSplit(const T& i_str, const T& i_delim)
{
std::vector<T> result;
size_t found = i_str.find(i_delim);
size_t startIndex = 0;
while (found != T::npos)
{
result.emplace_back(i_str.begin() + startIndex, i_str.begin() + found);
startIndex = found + i_delim.size();
found = i_str.find(i_delim, startIndex);
}
if (startIndex != i_str.size())
result.emplace_back(i_str.begin() + startIndex, i_str.end());
return result;
}由于这段代码确实依赖于字符串的参数,所以另一种方法是对字符类型进行模板,而不是字符串类型。像这样
template <typename T>
std::vector<std::basic_string<T>> StrSplit(const std::basic_string<T>& i_str, const std::basic_string<T>& i_delim)
{
std::vector<std::basic_string<T>> result;
size_t found = i_str.find(i_delim);
size_t startIndex = 0;
while (found != std::basic_string<T>::npos)
{
result.emplace_back(i_str.begin() + startIndex, i_str.begin() + found);
startIndex = found + i_delim.size();
found = i_str.find(i_delim, startIndex);
}
if (startIndex != i_str.size())
result.emplace_back(i_str.begin() + startIndex, i_str.end());
return result;
}发布于 2022-08-28 09:13:07
除了已经回答和注释过的显而易见的情况外,您还可以使用更短的形式来拆分字符串。C++在这方面有一个专门的功能。
std::regex_token_iterator。请读这里关于这件事。它存在于C++11之后,由于正则表达式的性质,它具有很强的通用性和强大性。(不过,也许对于某些用例来说太慢了)。
使用这个迭代器,您基本上可以遍历字符串中的模式。或者,将分隔符指定为模式。
结合std::vector的范围构造函数(5),结果通常是用于拆分字符串的一行。
例如,见:
#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <iterator>
using namespace std::string_literals;
template <typename C>
std::vector<std::basic_string<C>> split(const std::basic_string<C>& s, const std::basic_string<C>& delimiter) {
const std::basic_regex<C> re{ delimiter };
return { std::regex_token_iterator<std::basic_string<C>::const_iterator, C>( s.begin(), s.end(), re, -1),{} };
}
int main() {
for (const auto& s : split("aXXbXXcXXd"s, "XX"s)) std::cout << s << ' ';
for (const auto& ws : split(L"aaXXbbXXccXXdd"s, L"XX"s)) std::wcout << ws << ' ';
}https://stackoverflow.com/questions/73516265
复制相似问题