模板实例化错误

时间:2009-06-27 04:13:06

标签: c++ templates

我的模板功能“比较”定义如下。

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

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

3 个答案:

答案 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"));

你很高兴。