模板专业化无与伦比的错误

时间:2018-08-27 14:34:38

标签: c++

重新编辑:

这是 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


完整的屏幕截图(我已将最相关的部分装箱,很抱歉在此处发布这么大的图片)。

enter image description here enter image description here

3 个答案:

答案 0 :(得分:2)

C风格的字符串不是指针,而是数组。模板类型推导发生时,它推导Tconst 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");
}