模板专用化不匹配错误 重新编辑: 这就是C++引物第五所说的:

模板专用化不匹配错误 重新编辑: 这就是C++引物第五所说的:,c++,C++,第1版: 模板int比较(常数T&,常数T&) 第2版: 模板int比较(常量字符(&)[N],常量字符(&[M]) 版本1的专门化: 模板int比较(常量字符*常量和p1,常量字符*常量和p2) 例如,我们定义了两个版本的compare函数模板,一个引用数组参数,另一个引用常量。我们还专门针对字符指针这一事实对函数匹配没有影响。当我们对字符串文本调用compare时:compare(“hi”,“mom”) 这两个函数模板都是可行的,并且提供了与调用相同的良好(即精确)匹配。但是,具有字符数组参

第1版:

模板int比较(常数T&,常数T&)

第2版:

模板int比较(常量字符(&)[N],常量字符(&[M])

版本1的专门化:

模板int比较(常量字符*常量和p1,常量字符*常量和p2)

例如,我们定义了两个版本的
compare
函数模板,一个引用数组参数,另一个引用常量。我们还专门针对字符指针这一事实对函数匹配没有影响。当我们对字符串文本调用compare时:
compare(“hi”,“mom”)
这两个函数模板都是可行的,并且提供了与调用相同的良好(即精确)匹配。但是,具有字符数组参数的版本更为专业化(§16.3,第695页),并且被选择用于此调用


这本书说“两者都提供了同样好的匹配”,所以我认为第1版及其专门化应该编译得很好。但事实并非如此

所以“提供同样好的匹配”并不意味着它可以编译?这本书捉弄了我

我不明白为什么无法编译的原始代码段链接:


完整的背景截图(我已经把最相关的部分框起来了,很抱歉在这里发布这么大的图片)


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;
}

您正在向模板函数传递两个不同类型的参数(
“hi”
的类型是
常量字符[3]
“mom”
的类型是
常量字符[4]
),因此编译器无法找到与这两种类型匹配的
T

这与调用std::min(0,1U)
时得到的错误相同
std::min()
(它的一个重载)需要两个类型相同的参数,就像您的
compare()
函数一样

您的问题的一个可能解决方案是接受不同类型的参数:

template <typename T1, typename T2>
int compare(const T1&, const T2&);
模板
int比较(常数T1和,常数T2和);

这将在不编辑函数体的情况下工作。

编译器无法将其与现有模板之一匹配。如果仔细阅读第16.5节,您将了解它将调用模板类的第二个版本

函数调用有两种不同类型的参数
const char[3]
const char[4]
编译器找不到将两种不同数据类型作为参数的模板专用化。 下面的代码是解决方案之一

#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");
} 
#包括
#包括
使用名称空间std;
模板整数比较(常数T&,常数T&){

CUT查看一下您所得到的错误,并记住文字字符串实际上是数组(在错误消息中非常明确地表示)。RIK考虑重新读取错误消息:“参数的const t’(‘char(3)’和‘char(4)’)导出的冲突类型。。您的代码仅包含函数的版本1和版本3。本书中的版本2(
模板int compare(const char(&)[N],const char(&)[M]);//处理字符串文字的第二个版本
)缺少。我不明白你在问什么。这本书显示了工作代码。你删除了一些代码,但它停止了工作。你为什么认为这本书是错的?这本书很糟糕。这是解释函数模板重载与专用化的最糟糕的方法。@Rick是,但仍然需要推导出
t
,才能调用它。
template int compare(const char*const&p1,const char*const&p2)
有一个
T
const char*
,因此只有当
T
被这样推导并且正弦演绎失败时才会调用它。它永远不会调用它。谢谢。我重新编辑了这个问题。但我仍然对这本书为什么要说感到困惑“两者都提供了一个同样好的匹配”,而仅仅把版本1和它的专门化无法编译,演绎将失败,正如你所描述的。专门化在这里是完全无用的。我认为这本书是在捉弄我。@Rick这本书是错误的。
template int compare(const t&,const t&);
将永远无法与
compare(“您好,“妈妈”);
。也就是说,如果您有
比较(“妈妈”、“爸爸”)
,那么它将选择数组版本而不是常规版本。使用Version1和专用化,甚至提供
比较(“妈妈”、“爸爸”)
,仍然不会调用专门化版本。因此,在任何情况下,都不会调用版本1的专门化版本。
#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");
} 
#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");
}