2009-06-27 224 views
5

我有如下定义的模板函数“比较”。模板实例化错误

#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])”

我很困惑作为比较函数应该实例化字符指针而不是 字符数组。 不应该字符串文字总是衰减指针?

void compare(const T* a, const T* b) 

的原因是,该种不同尺寸的字符数组的实际上是不同的类型:如果更改声明

回答

4

正如格雷格的回答和评论所述,两种不同的数组类型(因为这是字符串文字是)是问题。您可能希望将函数保留为泛型类型,但将其重载用于字符指针和数组,这对于稍微不同地处理它们时非常有用。

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<char const*>("aa", "bbbb"); 

在另一方面,也许比较可以写成两种不同类型的工作?这对其他类型也是有用的,例如,如果a.size() < b.size()f(b)否则(f重载)可能会调用f(a)。 (T1和T2允许与下面的类型相同,这将取代你的功能,而不是像上述两个那样超载)。

template<typename T1, typename T2> 
void compare(T1 const& a, T2 const& b) { 
    // ... 
} 
6

你的榜样编译。如果在模板函数中使用了sizeof(T),编译器将不知道如何解决歧义。通过上面的声明,您正在调用带有指针T类型的模板函数,编译器在传递字符串时将愉快地解析为const char*

+0

@Greg,当前声明有什么问题? – chappar 2009-06-27 04:20:01

+0

您所写的声明要求函数比较采用两个完全相同类型的参数。 “const char [3]”和“const char [5]”不是同一类型。 – 2009-06-27 04:22:38

3

编译器会倾向于将字符串文字解释为字符缓冲区(如果可以的话)。如果不是,它可以将它们解释为const char *。然而,编译器不会做任何回溯以试图找到T的最佳解释。它并不那么复杂。一旦它决定T是一个const char [3],它就会继续。然后评估第二个参数失败。

如果用

compare(static_cast<const char *>("aa"),static_cast<const char *>("bbbb")); 

叫什么你是好去。