如何在C ++中编写泛型函数,将整数和字符串作为参数并修改它们?

时间:2012-10-04 08:57:45

标签: c++ templates

我正在尝试编写一个函数,它将一个字符串作为输入参数,三个输出参数可以是不同类型(至少是这个想法)和一个作为分隔符的char。

输入字符串由指定的char分隔,并且函数按顺序将每个以char结尾的字段分配给每个输出参数(此时它处理输入字符串,例如"a;bb;ccc",并且仅限于只有三个输出参数,但这不是问题)。

例如,对于10;200;3000这样的输入,我分别为第一个,第二个和第三个输出参数得到102003000

输出参数需要是字符串或整数类型,但由于我对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标准没问题,我必须向我们的技术负责人查询。

理想情况下,我想避免两种情况完全相同但每种类型都有不同签名的情况(一种用于字符串和 一个用于注册)。

非常感谢提前!

2 个答案:

答案 0 :(得分:3)

我会将字符串拆分为字符串(就像你一样),然后将它们转换为所需的类型。

您可以使用boost::lexical_caststd::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会比较安全!