C++ 根据模板参数的类型有条件地调用函数

Tha*_*dra 1 c++ templates c++11

假设我有几个函数来处理不同类型的参数。例如processInt用于处理int变量和 processString用于处理std::string变量。

int processInt(int i) 
{
    return i;
}

string processString(string s)
{
    return s;
}
Run Code Online (Sandbox Code Playgroud)

而且,我有一个名为的模板函数foo,它接受intstd::string作为参数。在这个函数内部,我需要根据作为参数发送给它的变量类型有条件地调用processIntor 。processStringfoo函数如下所示:

#include <type_traits>

template<typename T>
T foo(T value)
{
    T variable;
    if (std::is_same<T, int>::value) 
    {
        variable = processInt(value); 
    }
    else if (std::is_same<T, string>::value)
    {
        variable = processString(value);
    }
    return variable;
}

int main() {
    string s = "Abc";
    int i = 123;
    cout << foo(s) << " " << foo(i) << endl;     
}
Run Code Online (Sandbox Code Playgroud)

但是,使用上述foo函数我收到以下错误:


error: no matching function for call to 'processInt'
                variable = processInt(value); 
                           ^~~~~~~~~~
note: in instantiation of function template specialization 'foo<std::__cxx11::basic_string<char> >' requested here
    cout << foo(s) << " " << foo(i) << endl;    
            ^
note: candidate function not viable: no known conversion from 'std::__cxx11::basic_string<char>' to 'int' for 1st argument
int processInt(int i) 
    ^
error: no matching function for call to 'processString'
                variable = processString(value);
                           ^~~~~~~~~~~~~
note: in instantiation of function template specialization 'foo<int>' requested here
    cout << foo(s) << " " << foo(i) << endl;    
                             ^
note: candidate function not viable: no known conversion from 'int' to 'std::__cxx11::string' (aka 'basic_string<char>') for 1st argument
string processString(string s)
       ^
Run Code Online (Sandbox Code Playgroud)

源代码: https: //godbolt.org/z/qro8991ds

如何正确执行此操作,以根据泛型函数中模板参数的类型有条件地调用函数?

编辑

我喜欢使用单个foo函数而不重载或专门化,否则可能会出现一些代码重复。该foo函数可能有很多行。int但是,和的代码之间的区别string只是一行。

Som*_*ude 6

对于这样的事情,我建议模板和专业化:

// Declare base template
template<typename T>
T process(T);

// Specialization for integers
template<>
int process(int value)
{
    // ... code to process integers...
}

// Specialization for strings
template<>
std::string process(std::string value)
{
    // ... code to process strings...
}
Run Code Online (Sandbox Code Playgroud)

那么foo函数就变成了

template<typename T>
T foo(T value)
{
    return process(value);
}
Run Code Online (Sandbox Code Playgroud)

可选的普通旧重载应该也可以工作。