我正在尝试编写一个函数,它将一个字符串作为输入参数,三个输出参数可以是不同类型(至少是这个想法)和一个作为分隔符的char。
输入字符串由指定的char分隔,并且函数按顺序将每个以char结尾的字段分配给每个输出参数(此时它处理输入字符串,例如"a;bb;ccc"
,并且仅限于只有三个输出参数,但这不是问题)。
例如,对于10;200;3000
这样的输入,我分别为第一个,第二个和第三个输出参数得到10
,200
和3000
输出参数需要是字符串或整数类型,但由于我对C ++(特别是通用编程)的了解有限,我在编写一个不关心它的泛型函数时遇到了麻烦。 p>
我有以下代码:
template <typename T>
void parse_string (std::string &input, T &out1, T &out2, T &out3, const char delimiter)
{
while (out3 == "")
{
std::string temp = input.substr(0, input.find(delimiter));
input = input.substr(input.find(delimiter) +1);
if (out1 == "") { out1 = temp;}
else if (out2 == "") { out2 = temp;}
else { out3 = temp;}
}
}
它适用于字符串,但显然不适用于整数。
我怀疑我在检查参数是否为空的位置出错(我不知道的其他部分)。
你能帮我改进吗?
另外,我欢迎任何关于改进逻辑本身的想法(也许我需要使用可变参数模板来使参数的数量变得灵活,但是 如果C ++ 11标准没问题,我必须向我们的技术负责人查询。
理想情况下,我想避免两种情况完全相同但每种类型都有不同签名的情况(一种用于字符串和 一个用于注册)。
非常感谢提前!
答案 0 :(得分:3)
我会将字符串拆分为字符串(就像你一样),然后将它们转换为所需的类型。
您可以使用boost::lexical_cast
或std::stringstream
template <typename To, typename From>
To cast(const From &arg)
{
std::stringstream s;
s << arg;
To res;
s >> res;
if (s.fail())
{
//throw some_exception();
}
return res;
}
在任何情况下,如果您有boost
可用,那么这是正确的方法
答案 1 :(得分:2)
#include <algorithm>
#include <string>
#include <sstream>
template <typename T1, typename T2, typename T3>
void parse_string(const std::string& input, T1& out1, T2& out2,
T3& out3, char delimeter)
{
std::istringstream is1(input);
std::string field;
for (int i = 0; std::getline(is1, field, delimeter) && i < 3; ++i)
{
std::istringstream is2(field);
switch (i)
{
case 0: is2 >> out1; break;
case 1: is2 >> out2; break;
case 2: is2 >> out3; break;
}
if (is2.fail())
{
// do something about invalid type conversion?
}
}
// up to you to decide what to do if the string has too
// many or too few fields
}
lexical_cast会比较安全!