C++ 如何改进这段关于strtok\u r的代码

C++ 如何改进这段关于strtok\u r的代码,c++,string,strtok,C++,String,Strtok,我想通过分隔符从std::string中提取一些令牌,并编写如下函数,但仍然存在错误: enum TO_TYPE { TO_INT=0, TO_FLOAT, TO_STRING}; template<typename T> vector<T> string_to_token(string &str, const char* delim, TO_TYPE to_type) { char *p=new char[str

我想通过分隔符从std::string中提取一些令牌,并编写如下函数,但仍然存在错误:

    enum TO_TYPE { TO_INT=0, TO_FLOAT, TO_STRING};

    template<typename T>
    vector<T> string_to_token(string &str, const char* delim, TO_TYPE to_type)
    {
        char *p=new char[str.size()];
        memcpy(p,str.c_str(),str.size());
        switch(to_type)
        {
        case TO_INT:
        {
            vector<int> res;
            char *token;
            char *state;
            for (token = strtok_r(p, delim, &state);
                 token != NULL;
                 token = strtok_r(NULL, delim, &state))
            {
                res.push_back(atoi(token));
            }
            delete[] p;
            return res;
        }
            break;
        case TO_FLOAT:
        {
            vector<float> res;
            char *token;
            char *state;
            for (token = strtok_r(p, delim, &state);
                 token != NULL;
                 token = strtok_r(NULL, delim, &state))
            {
                res.push_back(atof(token));
            }
            delete[] p;
            return res;
        }
            break;
        case TO_STRING:
        {
            vector<string> res;
            char *token;
            char *state;
            for (token = strtok_r(p, delim, &state);
                 token != NULL;
                 token = strtok_r(NULL, delim, &state))
            {
                res.push_back(string(token));
            }
            delete[] p;
            return res;
        }
            break;
        }
    }
enum TO_TYPE{TO_INT=0,TO_FLOAT,TO_STRING};
模板
向量字符串\u到\u标记(字符串&str,常量字符*delim,到\u类型到\u类型)
{
char*p=新字符[str.size()];
memcpy(p,str.c_str(),str.size());
开关(至_型)
{
案件编号:
{
向量res;
字符*令牌;
字符*状态;
for(token=strtok_r(p、delim和state);
令牌!=NULL;
token=strtok_r(NULL、delim和state))
{
res.push_back(atoi(token));
}
删除[]p;
返回res;
}
打破
浮点数的情况:
{
向量res;
字符*令牌;
字符*状态;
for(token=strtok_r(p、delim和state);
令牌!=NULL;
token=strtok_r(NULL、delim和state))
{
res.push_back(atof(token));
}
删除[]p;
返回res;
}
打破
大小写到字符串:
{
向量res;
字符*令牌;
字符*状态;
for(token=strtok_r(p、delim和state);
令牌!=NULL;
token=strtok_r(NULL、delim和state))
{
res.push_back(字符串(令牌));
}
删除[]p;
返回res;
}
打破
}
}
用法:

    string str="lab,yuv,hsv";
    vector<string> colorspace=string_to_token<string>(str,",");
string str=“实验室、yuv、hsv”;
向量颜色空间=字符串\u到\u标记(str,“,”);
它在
返回res
行中有错误

我曾尝试使用
void(*change\u func)(char*temp\u str)
作为回调函数,但我不知道如何实现它。
如果你方便的话,能给我一些建议吗?非常感谢。

出现错误的原因是,您的模板将在编译时指定为(示例为
int
):

模板
向量字符串\u到\u标记(字符串&str,常量字符*delim,到\u类型到\u类型)
{
// ... 
开关(至_型)
{
案件编号:
{
向量res;
// ...
return res;//这没问题
}
打破
浮点数的情况:
{
向量res;
// ...
return res;//这将尝试为向量返回向量
}
打破
大小写到字符串:
{
向量res;
// ...
return res;//这将尝试为向量返回向量
}
打破
}
}
实际上,您正试图用此函数解决两个问题:

  • 标记化(参见解决方案)

  • 字符串转换

考虑将此函数分为两部分:

  • 首先是一个非模板函数,它将字符串标记为std::vector

  • 第二,转换(可以通过类型轻松模板化):

代码:

std::vector strings=tokenize(str,”,”;//见上面的链接
std::vector int{strings.size()};
std::transform(strings.begin()、strings.end()、ints.begin(),
[](const std::string&s){return std::stoi(s);});

枚举中将其模板化为_TYPE
并在运行时保存一个分支谢谢。但我不太清楚你说了什么。我已经使用了模板参数,但它不起作用。我已经实现了三个独立的功能。非常清晰的解决方案。非常感谢。我应该更多地了解C++。
template<>
vector<int> string_to_token(string &str, const char* delim, TO_TYPE to_type)
{
    // ... 
    switch(to_type)
    {
    case TO_INT:
    {
        vector<int> res;
        // ...
        return res; // this is OK
    }
        break;
    case TO_FLOAT:
    {
        vector<float> res;
        // ...
        return res; // this will attempt to return vector<float> for a vector<int>
    }
        break;
    case TO_STRING:
    {
        vector<string> res;
        // ...
        return res; // this will attempt to return vector<string> for a vector<int>
    }
        break;
    }
}
std::vector<std::string> strings = tokenize(str, ","); // see link above
std::vector<int> ints{strings.size()};
std::transform(strings.begin(), strings.end(), ints.begin(),
    [](const std::string& s) { return std::stoi(s); });