简体   繁体   English

如何用C ++编写一个将整数和字符串都作为参数并对其进行修改的泛型函数?

[英]How to write a generic function in C++ that takes as arguments both integers and strings and modifies them?

I'm trying to write a function that takes as an input argument a string, three output arguments that can be of varying types (at least that's the idea) and a char that is a delimiter. 我正在尝试编写一个函数,该函数将一个字符串,三个可以具有不同类型的输出参数(至少是这样)和一个作为分隔符的char作为输入参数。

The input string is delimited by the specified char and the function assigns each char-terminated field to each of the output arguments in order (at the moment it takes care of input strings such as "a;bb;ccc" and is limited to three output arguments only but that's not the problem). 输入字符串由指定的char分隔,并且该函数将每个以char终止的字段按顺序分配给每个输出参数(目前,它负责输入字符串,例如"a;bb;ccc" ,并且限制为三个仅输出参数,但这不是问题)。

For example with an input such as 10;200;3000 I'd get 10 , 200 and 3000 for the first, second and third output arguments respectively 例如与输入诸如10;200;3000我会得到102003000分别用于第一,第二和第三输出参数

The output arguments need to be of either string or integer types, but due to my limited knowledge of C++ (and in particular generic programming) I'm having trouble writing a generic function that doesn't care about that. 输出参数必须是字符串或整数类型,但是由于我对C ++(特别是通用编程)的了解有限,因此我在编写不关心它的通用函数时遇到了麻烦。

I have the following code: 我有以下代码:

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;}
    }
}

and it works fine for strings but obviously not for integers. 它适用于字符串,但显然不适用于整数。

I suspect I'm going wrong in the bits where I check if the argument is empty (among other parts I don't know about). 我怀疑我在检查参数是否为空的地方出错(在其他我不知道的地方)。

Could you please help me improve it? 您能帮我改善它吗?

Also, I would welcome any ideas on improving the logic itself (perhaps I'd need to go with the variadic templates to make the number of arguments flexible, but I'd have to check with our technical lead if C++11 standards are okay). 另外,我也欢迎任何关于改进逻辑本身的想法(也许我需要使用可变参数模板来使参数数量灵活一些,但是如果C ++ 11标准是标准的话,我必须与我们的技术负责人核对一下好的)。

Ideally I'd like to avoid the situation where I have the exact same function twice but with a different signature for each of the types (one for strings and one for ints). 理想情况下,我想避免这样的情况:我两次具有完全相同的功能,但每种类型的签名不同(一个用于字符串,一个用于整数)。

Many thanks in advance! 提前谢谢了!

I would go with splitting the string into strings (as you do) and then converting them to required type. 我将把字符串拆分为字符串(如您所愿),然后将其转换为所需的类型。

You can use boost::lexical_cast for that, or std::stringstream 您可以为此使用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;
}

In any case if you have boost available it is the right way to go 无论如何,如果您有boost ,这是正确的方法

#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 would be safer tho! lexical_cast会更安全!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM