没有模板<>的 C++ 模板特化

ako*_*hko 1 c++

我有两个版本的程序。第一的:

template<class T>
void f(T i, T j) = delete;

template<>
void f(int i, int j) {
    cout << i << j << endl;
};

int main()
{
    f(1.5, 2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第二:

template<class T>
void f(T i, T j) = delete;

void f(int i, int j) {
    cout << i << j << endl;
};

int main()
{
    f(1.5, 2);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第一个版本不会编译,因为1.52有不同的类型。在我删除的第二个版本中,template<>因此1.5将转换为1并且程序将成功运行。那么,当我们 remove 时template<>,它仍然是模板特化,还是别的什么?除了隐式类型转换之外还有什么区别吗?有用吗?

Max*_*kin 6

对于代码中的(非限定)函数调用,f(1.5, 2)编译器会构建一组候选函数,其中包含常规函数和从模板生成的函数。在解析和替换模板参数之前,函数模板不是函数。有关完整详细信息,请参阅重载解析

f是函数模板,它不能Tdoubleand类型的参数中推导出来int。不考虑模板特化,因为模板参数推导失败。可行的函数集为空,编译无法编译调用。

T如果您将其称为编译器,则可以解决编译器的歧义,f<int>但此类调用f仅考虑模板(因为您明确指定了模板参数)。

如果你对f非模板进行完全特化,它就变成了一个常规函数。在这种情况下,模板参数推导仍然像以前一样失败,但现在有另一个函数f并且候选函数集包含该函数f。可以使用提供的参数调用它,因为double它隐式转换为int.

对于函数参数,其类型不从参数类型推断(即,参数类型是不是一个模板参数或显式指定的模板参数)的编译器将认为参数类型的隐式转换函数的参数类型和doubleint在隐式转换,这就是为什么调用重载函数会f成功。