没有模板函数自动从' int '转换为' float '

No Automatic Cast from `int` to `float` with Template Function

本文关键字:int 转换 float 函数      更新时间:2023-10-16

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

除了想知道为什么会发生这个错误,

调用Add(1.f, 2)时,第一个参数类型为float,第二个参数类型为int

编译器必须将第一个实参转换为int或第二个实参转换为float。因为它们都需要转换,所以它们都是很好的候选人。两者不能孰优孰劣。

我想知道如何通过修改模板函数

来解决以下错误

可以将函数模板修改为:

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

或to(感谢@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.

Just do:

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

与唯一的T一样,一次推导为int,一次推导为double

当你有

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)

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

可以显式指定类型:

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

既然标准已经提供了函数,为什么还要编写自己的函数呢?

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

我想知道如何通过修改模板函数

来解决以下错误
这样的

:

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