模板函数如何与可能共享交集的多个类型名一起工作?

One*_*ee7 0 c++ templates generic-programming

我是 C++ 新手,目前正在尝试了解模板函数的工作原理。首先我想添加两个相同类型的数值,这很容易理解。

template <typename T>
T add(T a, T b){return a+b;}
int main(){
    float a_f=2.5;float b_f=1.5;float c_f;
    int a_i=2;int b_i=1;int c_i;
    c_f = add(a_f, b_f);
    c_i = add(a_i, b_i);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

接下来我想添加两个具有不同和相同类型的数字。我天真的假设是这样的:

template<typename R, typename S, typename T>
R add(S a, T b){return a+b;}
int main(){
    float a=3.2; int b=2;
    auto result1 = add(a,b);    // error: no matching function for call to ‘add(float&, int&)’
    auto result2 = add(a,a);    // error: no matching function for call to ‘add(float&, float&)’
    auto result3 = add(b,b);    // error: no matching function for call to ‘add(int&, int&)’
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我知道这种方法是不正确的,因为 typename 共享有关数据类型的交集,因此声明本身不可能正确。

如何实现一个简单的 add() 函数将两个数值相加,而不管类型如何?

Nat*_*ica 6

问题不在于交集,而在于它不能推导出R。在

template<typename R, typename S, typename T>
R add(S a, T b){return a+b;}
Run Code Online (Sandbox Code Playgroud)

没有什么告诉编译器R应该是什么。它不是从您将结果分配给的变量中推导出来的,并且您没有指定它,因此没有它可以执行的有效调用。要解决此问题,您可以摆脱R并使用auto返回类型来为您推断它

template<typename S, typename T>
auto add(S a, T b){return a+b;}
Run Code Online (Sandbox Code Playgroud)


Max*_*kin 5

如何add()实现一个简单的函数,将两个数值相加,而不管类型如何?

在 C++14 中:

template<class T, class U>
auto add(T t, U u) {
    return t + u;
}
Run Code Online (Sandbox Code Playgroud)

在上面,返回值的类型是从表达式的类型推导出来的t + u

C++11 不推导出返回类型,但允许尾随返回类型,因此 C++11 版本是:

template<class T, class U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以在“{”之前添加“-&gt; decltype(t + u)”以实现 C++11 兼容性。 (4认同)
  • @One3Three7我更喜欢`typename`并且希望其他人这样写,因为它可以更好地表达一个人的意图。可读性很重要。 (2认同)