带有参数的重载模板的模糊调用(const t&const t&) or (const char (&)[N], const char (&)[M])

时间:2022-10-29 12:10:09

For the following code:

对于下面的代码:

#include <iostream>
using std::cout; using std::endl;

template <typename T>
int compare(const T&, const T&) {
    cout << __PRETTY_FUNCTION__ << endl;
    return 0;
}
template <size_t N, size_t M>
int compare(const char (&)[N], const char (&)[M]) {
    cout << __PRETTY_FUNCTION__ << endl;
    return 0;
}

int main(int argc, char *argv[]) {
    compare("hi", "is");
}

When I compiles the code with g++ -std=c++1y, it complains:

当我用g++ -std=c++1y编译代码时,它会抱怨:

error: call of overloaded ‘compare(const char [3], const char [3])’ is ambiguous
     compare("hi", "is");

According to the rules of template overloading, viable functions are:

根据模板重载的规则,可行函数为:

compare(const T&, const T&) with T = char [3]
compare(const char (&)[N], const char (&)[M]) with N = 3ul, M = 3ul

They both provide an equally good (i.e., exact) match to the call. So I should check which one is more specialized.

它们都提供了同样的好处。,准确的)匹配呼叫。所以我应该检查哪一个更专业。

But according to my limited knowledge, const T& is more general than const char (&)[N]. So I think that compare(const char (&)[N], const char (&)[M]) is more specialized. But why is this call ambiguous?

但根据我有限的知识,const t&is more general than const char (&)[N]。因此我认为比较(const char (&)[N], const char (&)[M])更为专门化。但是,为什么这个称呼含糊不清呢?

1 个解决方案

#1


10  

The first overload compare(const T&, const T&) forces both parameters to be the same type, while the second overload doesn't. So in this regard the first overload is more specific.

第一个重载比较(const t&const t&)强制两个参数都是相同的类型,而第二个重载则没有。所以在这方面,第一个过载更具体。

However, the second overload forces both parameters to be char arrays, so it is more specific in that regard.

但是,第二个重载将两个参数都强制为char数组,因此在这方面更具体。

Therefore, neither overload can be said to be more specialized than the other, and the result is the ambiguity error.

因此,任何超载都不能说比另一个更专业,结果是歧义错误。

Another way to look at it is that each overload can accept an input that the other doesn't: Only the first overload will accept a call where both arguments are int&. And only the second overload will accept a call where the arguments are char (&)[2] and char (&)[3].

另一种查看方法是,每个重载都可以接受另一个不存在的输入:只有第一个重载将接受两个参数都为int&的调用。并且只有第二个重载会接受[2]和char(&)[3]的调用。

If you change the second overload to

如果你改变第二个过载。

template <size_t N> int compare(const char (&)[N], const char (&)[N])

it will fix the error, as this is now strictly more specific than the first overload.

它将修正错误,因为现在严格地比第一个重载更具体。

#1


10  

The first overload compare(const T&, const T&) forces both parameters to be the same type, while the second overload doesn't. So in this regard the first overload is more specific.

第一个重载比较(const t&const t&)强制两个参数都是相同的类型,而第二个重载则没有。所以在这方面,第一个过载更具体。

However, the second overload forces both parameters to be char arrays, so it is more specific in that regard.

但是,第二个重载将两个参数都强制为char数组,因此在这方面更具体。

Therefore, neither overload can be said to be more specialized than the other, and the result is the ambiguity error.

因此,任何超载都不能说比另一个更专业,结果是歧义错误。

Another way to look at it is that each overload can accept an input that the other doesn't: Only the first overload will accept a call where both arguments are int&. And only the second overload will accept a call where the arguments are char (&)[2] and char (&)[3].

另一种查看方法是,每个重载都可以接受另一个不存在的输入:只有第一个重载将接受两个参数都为int&的调用。并且只有第二个重载会接受[2]和char(&)[3]的调用。

If you change the second overload to

如果你改变第二个过载。

template <size_t N> int compare(const char (&)[N], const char (&)[N])

it will fix the error, as this is now strictly more specific than the first overload.

它将修正错误,因为现在严格地比第一个重载更具体。