这是 C ++ Primer 5th 所说的:
版本1:
template <typename T> int compare(const T&, const T&);
版本2:
template<size_t N, size_t M> int compare(const char (&)[N], const char (&)[M]);
版本1的特殊化:
template <> int compare(const char* const &p1, const char* const &p2);
例如,我们已经定义了
compare
函数模板的两个版本,一个引用了数组参数的,另一个const T&
。我们还具有专门针对字符指针的功能,这一事实对功能匹配没有影响。当我们在字符串文字上调用compare时:compare("hi", "mom")
这两个函数模板都是可行的,并且可以为调用提供相同的(即精确的)匹配。。但是,具有字符数组参数的版本更加专业(第16.3页,第(695)。
这本书说“两者都提供了同样出色的匹配”,所以我认为放置版本1及其专业知识应该很好。但事实并非如此。
因此“提供同样出色的匹配”并不意味着它可以编译?这本书对我起了招吗?
我不明白为什么无法编译的原始代码段链接: https://wandbox.org/permlink/oSCDWad03nELC9xs
完整的屏幕截图(我已将最相关的部分装箱,很抱歉在此处发布这么大的图片)。
答案 0 :(得分:2)
C风格的字符串不是指针,而是数组。模板类型推导发生时,它推导T
为const char[3]
或const char[4]
。由于这些冲突,编译器无法推断T
并在此处停止。
template<>
int compare(const char* const &p1, const char* const&p2) {
cout << "const char* const" << endl;
return 3;
}
之所以不会被调用,是因为它依赖于T
的推论和匹配const char*
,并且编译器无法推断T
。专业化不是重载,而是特定于T
的秘诀。如果无法推论T
,则不会调用专门化(即使它是有效的重载)。
如果您要重载该函数,而不要使用以下内容提供专门化then it would compile:
int compare(const char* const &p1, const char* const&p2) {
cout << "const char* const" << endl;
return 3;
}
答案 1 :(得分:2)
您正在将不同类型的两个参数传递给模板函数("hi"
的类型为const char [3]
,"mom"
的类型为{{1 }}),因此编译器无法找到与两种类型都匹配的const char [4]
。
与调用T
会得到相同的错误; std::min(0, 1U)
(其重载之一)期望两个参数类型相同,就像您的std::min()
函数一样。
您问题的一种可能的解决方案是接受不同类型的参数:
compare()
这无需编辑函数主体即可起作用。
答案 2 :(得分:0)
编译器无法将其与现有模板之一匹配。如果您仔细阅读第16.5节,您将理解它将调用模板类的第二版。
函数调用具有2种不同类型的参数const char[3]
,const char [4]
编译器无法找到采用2种不同数据类型作为参数的模板特殊化。
下面的代码是解决方案之一。
#include <iostream>
#include <string>
using namespace std;
template <typename T> int compare(const T&, const T&) {
cout << "const T" << endl;
return 3;
}
template<size_t N, size_t M>
int compare(const char (&p)[N], const char (&q)[M]) {
cout<<p<<" "<<q<<endl;
return 3;
}
int main()
{
compare("hi", "mom");
}
其他解决方案如下。它需要2种不同的类型并访问变量。
#include <iostream>
#include <string>
using namespace std;
template <typename T> int compare(const T&, const T&) {
cout << "const T" << endl;
return 3;
}
template <typename T1, typename T2>
int compare(const T1&p, const T2&q){
cout<<p<<" "<<q<<endl;
return 3;
}
int main()
{
compare("hi", "mom");
}