没有使用模板函数从`int`自动转换为`float`

时间:2015-10-02 19:30:09

标签: c++ c++11 template-function

经过多年的c ++编码,今天我被问到一个简单的问题,但实际上我找不到它的答案,所以在这里我就是人。

除了想知道为什么这个错误发生之外,我想通过仅修改模板函数来了解如何我可以解决以下错误(没有更改main()功能)

template <class T>
T Add(T first, T second)
{
    return first + second;
}

int main()
{
    auto sample_1 = Add(1, 2); // Works
    auto sample_2 = Add(1.f, 2.f); // Works
    auto sample_3 = Add(1.f, 2); // Error: no instance matches the argument types: (double, int)
    return 0;
}

6 个答案:

答案 0 :(得分:16)

  

除了想知道为什么会发生这种错误之外,

当您致电Add(1.f, 2)时,第一个参数类型为float,第二个参数类型为int

编译器必须将第一个参数转换为int或将第二个参数转换为float。由于它们都需要转换,因此它们同样适合。一个人不能优先于另一个人。

  

我想通过仅修改模板函数

来了解如何解决以下错误

您可以将功能模板更改为:

template <class T1, class T2>
auto Add(T1 first, T2 second)
{
    return first + second;
}

或(感谢@PiotrSkotnicki):

template <class T>
T Add(T first, decltype(first) second)
{
    return first + second;
}

在这种情况下,second的类型不会从传递给函数的参数中推断出来。 first的类型是从第一个参数推导出来的,second的类型被强制与first的类型相同。

Add(1.2f, 2);  // The first argument is deduced to be float
               // The second argument is forced to be float.

Add(2, 1.2f);  // The first argument is deduced to be int
               // The second argument is forced to be int.

答案 1 :(得分:9)

只是做:

template <class T1, class T2>
auto Add(T1 first, T2 second)
{
    return first + second;
}

与唯一T一样,它被推断为int一次,double ...

答案 2 :(得分:4)

当你有

template <class T>
T Add(T first, T second)

firstsecond的类型必须相同。如果您想采用两种不同的类型,则可以添加第二个模板参数

template <class T1, class T2>
auto Add(T1 first, T2 second)

或C ++ 11

template <class T1, class T2>
auto Add(T1 first, T2 second) -> decltype(first + second)

答案 3 :(得分:3)

编译器正在尝试推导出可用于创建与签名匹配的函数的模板类型。由于参数是不同的类型,因此无法执行此操作。

您可以明确指定类型:

auto sample_3 = Add<float>(1.f, 2);

但你说你不想这样做。

您可以将功能更改为两个模板类型:

template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
    T1 p;
    p = first + second;
    return p;
}

但是现在你必须假设要返回哪种类型。

我从未尝试使用auto作为返回类型,但显然可行:http://ideone.com/1qO95w

template <class T1, class T2>
auto Add(T1 first, T2 second)
{
    auto p = first + second;
    return p;
}

答案 4 :(得分:2)

为什么在标准提供它们时编写自己的函数?

在c ++ 11中,您可以使用:

#include <functional>
int main()
{
    auto sample_1 = std::plus<float> () ( 1, 2 ); // Works
    auto sample_2 = std::plus<float> () ( 1.f, 2.f ); // Works
    auto sample_3 = std::plus<float> () ( 1.f, 2 ); // Works
    return 0;
}

在c ++ 14中:

#include <functional>
int main()
{
    auto sample_1 = std::plus<> () ( 1, 2 ); // Works
    auto sample_2 = std::plus<> () ( 1.f, 2.f ); // Works
    auto sample_3 = std::plus<> () ( 1.f, 2 ); // Works
    return 0;
}

答案 5 :(得分:1)

  

我想通过仅修改模板函数

来了解如何解决以下错误

就像那样:

template <class T1, class T2>
T1 Add(T1 first, T2 second)
{
    T1 p;
    p = first + second;
    return p;
}

int main()
{
    auto sample_1 = Add(1, 2);
    auto sample_2 = Add(1.f, 2.f);
    auto sample_3 = Add(1.f, 2);
    return 0;
}