如何将函数转换为模板函数
C++ - How to convert a function to a template function
我有一个C++
函数,它接受逗号分隔的字符串并在std::vector<std::string>
中分割:
std::vector<std::string> split(const std::string& s, const std::string& delim, const bool keep_empty = true) {
std::vector<std::string> result;
if (delim.empty()) {
result.push_back(s);
return result;
}
std::string::const_iterator substart = s.begin(), subend;
while (true) {
subend = std::search(substart, s.end(), delim.begin(), delim.end());
std::string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(temp);
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}
然而,我真的希望能够将此函数应用于多种数据类型。例如,如果我输入std::string
:
1,2,3,4,5,6
那么我希望函数的输出是int
s的向量。我对C++
相当陌生,但我知道有一种叫做template
类型的东西,对吧?是否可以将此函数创建为通用模板?还是我误解了template
功能的工作方式?
可以将模板函数声明为:
template<class ReturnType>
std::vector<ReturnType> split(const std::string&, const std::string&, const bool = true);
,然后对你想要允许的每种向量类型进行专门化:
template<>
std::vector<std::string> split(const std::string& s, const std::string& delim, const bool keep_empty) {
// normal string vector implementation
}
template<>
std::vector<int> split(const std::string& s, const std::string& delim, const bool keep_empty) {
// code for converting string to int
}
// ...
你可以在这里阅读关于string到int的转换。
你将需要调用split
作为:
auto vec = split<int>("1,2,3,4", ",");
你可以"模板化"这个函数-启动它,你只需要在函数之前用'std::vector and add
template '替换std::vector<std::string>
。但是你需要注意如何将字符串放入结果向量中。在当前的实现中,只有
result.push_back(temp);
因为result
是string类型的vector,而temp是string类型的。在一般情况下,这是不可能的,如果你想使用这个函数,例如vector<int>
,这一行将无法编译。然而,这个问题很容易用另一个函数来解决——还是模板——它将字符串转换成你想要使用split
的任何类型。我们把这个函数命名为convert
:
template<typename T> T convert(const std::string& s);
那么你需要为你需要的任何类型提供这个函数的专门化。例如:
template<> std::string convert(const std::string& s) { return s; }
template<> int convert(const std::string& s) { return std::stoi(s); }
通过这种方式,您不需要像另一个答案所建议的那样专门化整个函数,只需根据类型专门化部分即可。对于
行也应执行相同的操作。result.push_back(s);
您的函数可以很容易地一般化,使用Boost.LexicalCast返回任意类型的vector
。唯一的问题是:
if (delim.empty()) {
result.push_back(s);
return result;
}
这只适用于现在,因为输入和输出类型都是std::string
,但显然不能工作,如果你返回的vector
包含std::string
以外的类型。使用boost::lexical_cast
执行这样的无效转换将导致抛出boost::bad_lexical_cast
。所以也许你想重新考虑这部分,但除此之外,实现是直截了当的。
#include <boost/lexical_cast.hpp>
template<typename Result>
std::vector<Result>
split(const std::string& s, const std::string& delim, const bool keep_empty = true)
{
std::vector<Result> result;
if (delim.empty()) {
result.push_back(boost::lexical_cast<Result>(s));
return result;
}
std::string::const_iterator substart = s.begin(), subend;
while (true) {
subend = std::search(substart, s.end(), delim.begin(), delim.end());
std::string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(boost::lexical_cast<Result>(temp));
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}
基本上,我所做的就是使结果类型成为模板参数,并替换了
result.push_back(x);
result.push_back(boost::lexical_cast<Result>(x));
如果您不能使用Boost,请看看这个答案,它展示了如何使用stringstream
将字符串转换为其他类型。
- 如何使用Rcpp将R函数转换为C++函数
- C++函数转换为 C# 函数
- 将 C 函数转换为 C++ 以检查数字是否有效
- C++:从重载函数转换为 std::function
- 将 C 函数转换为C++语言
- C++隐式构造函数转换,后跟类型向上转换
- 将 lambda 函数转换为具有混合 lambda 引入器和参数列表的函子结构
- 通过 Boost Python 将 Python 函数转换为 C++,用作回调
- 如何将 MATLAB 图像处理库内置函数转换为 MATLAB 编码器代码生成不支持的 C++?
- 如何将函数转换为 lambda 函数
- 自定义函数转换错误?
- 将 C# 哈希函数转换为C++
- 将 lambda 函数转换为另一个编译单元中的普通函数会缩短编译时间吗?
- 加快 R 性能或将 R 函数转换为C++函数
- 将成员函数转换为指向成员函数的指针
- 将MATLAB炒作函数转换为C
- Rcpp - 用二进制函数转换数字向量?
- C lambda函数转换误差
- 此语法中的构造函数转换错误
- 将函数转换为find_if lambda