13

经过多年的 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;
}
4

6 回答 6

16

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

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

编译器必须将第一个参数转换为 aint或将第二个参数转换为 a 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从第一个参数推导出类型 of并且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.
于 2015-10-02T19:35:32.583 回答
9

做就是了:

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

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

于 2015-10-02T19:34:42.927 回答
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)
于 2015-10-02T19:34:58.930 回答
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;
}
于 2015-10-02T19:36:18.190 回答
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;
}
于 2015-10-03T00:13:44.073 回答
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;
}
于 2015-10-02T19:34:49.043 回答