我的模板功能“比较”定义如下。
#include<iostream>
using namespace std;
template<typename T>
void compare(const T&a, const T& b)
{
cout<<"Inside compare"<<endl;
}
main()
{
compare("aa","bb");
compare("aa","bbbb");
}
当我实例化比较相同长度的字符串文字时,编译器不会抱怨。当我用不同长度的文字做它时,它说“错误:没有匹配调用比较的函数(const char [3],const char [5])”
我很困惑,因为比较函数应该用字符指针而不是实例化 字符数组。 字符串文字不应该总是衰减到指针吗?
答案 0 :(得分:6)
如果您将声明更改为:
,则会编译您的示例void compare(const T* a, const T* b)
原因是不同大小的字符数组的类型实际上是不同的类型。如果在模板函数中使用sizeof(T)
,编译器将不知道如何解决模糊性。使用上面的声明,您将调用一个带有指针到T类型的模板函数,当传递字符串时,编译器将很乐意将其解析为const char*
。
答案 1 :(得分:4)
正如Greg的回答和评论中所述,两个不同的数组类型(因为这是字符串文字)是问题所在。您可能希望将函数保留为泛型类型的原样,但是对于字符指针和数组重载它,当您想要稍微区别对待它们时,这非常有用。
void compare(char const* a, char const* b) {
// do something, possibly use strlen()
}
template<int N1, int N2>
void compare(char const (&a)[N1], char const (&b)[N2]) {
// ...
}
如果要指定compare应该明确地使用字符指针,那么数组将自动转换:
compare<char const*>("aa", "bbbb");
另一方面,也许比较可以写成两种不同类型的工作?这对于其他类型也是有用的,例如,如果f(a)
可能会调用a.size() < b.size()
,否则调用f(b)
(f
会重载)。 (T1和T2允许在下面使用相同的类型,这将取代你的功能而不是像上面那样重载它。)
template<typename T1, typename T2>
void compare(T1 const& a, T2 const& b) {
// ...
}
答案 2 :(得分:3)
如果可以的话,编译器会更喜欢将字符串文字解释为字符缓冲区。如果没有,它可以将它们解释为const char *。 但是,编译器不会进行任何回溯以试图找到对T的最佳解释。它并不复杂。一旦它确定T是一个const char [3],它就继续前进。然后评估第二个参数失败。
如果你用
打电话compare(static_cast<const char *>("aa"),static_cast<const char *>("bbbb"));
你很高兴。