1

我有这个来自 C++ 入门第 5 版的例子:

template <typename T>
int compare(T const& x, T const& y) // in the book const T&
{
    cout << "primary template\n"; // I've added print statements
    if(std::less<T>()(x, y))
        return -1;
    if(std::less<T>()(y, x))
        return 1;
    return 0;
}

template <unsigned N, unsigned M>
int compare(char const(&rArr1)[N], char const(&rArr2)[M])
{
    cout << "overload for arrays\n";
    return strcmp(rArr1, rArr2);
}

template <>
int compare(char const* const &p1, char const* const &p2)
{
    cout << "specilization for char* const\n";
    return strcmp(p1, p2);
}


int main()
{
    std::cout << compare("Hi", "Mom") << '\n';
}

“我们将特定函数定义为特化函数还是独立的非模板函数都会影响函数匹配。例如,我们定义了两个版本的比较函数模板,一个引用数组参数,另一个引用数组参数const T&。我们还专门针对字符指针进行了专门化这一事实对函数匹配没有影响。当我们在字符串文字上调用 compare 时:

compare("hi", "mom");

两个函数模板都是可行的,并且为调用提供了同样好的(即精确)匹配。但是,带有字符数组参数的版本更专业(第 16.3 节,第 695 页),并被选择用于此调用。”

  • 我认为这是不正确的:“compare("hi", "mom");两个模板都是可行的”,因为我看到第一个版本T const&, T const&不可行,因为它被实例化为:

      compare(char const(&rArra1)[3], char const(&rArr2)[4]);
    

在这种情况下大小不同,并且我们知道数组的大小是其类型的一部分,因此这里两个文字字符串具有两种不同的类型,因此模板参数推导将失败,因此该实例化被拒绝。就好像我们写了:compare(5, 0.); // int, double 因此编译器无法推断出此处需要的唯一类型。

  • 为了确认我在说什么,如果我注释掉采用数组类型的版本,那么代码将不会针对具有不同大小的两个文字字符串的调用进行编译。

  • 让我感到困惑的是,如果我注释掉数组类型的版本,即使我有第三个版本(指向字符串的指针),代码也不会编译!这是因为专业化不会影响功能匹配吗?被主模板拒绝的东西被它的所有特化拒绝了?

请说清楚。谢谢!

4

0 回答 0