如何在函数模板的显式特化中推导出模板参数?

Car*_*sel 6 c++ template-specialization

考虑以下案例:

#include <iostream>

template <class T> void f(T) { std::cout << "#1\n"; } // #1
template <> void f(const int) { std::cout << "#2\n"; } // #2

int main() {
    f<const int>(1); // call #1
    f<int>(1);       // call #2
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

似乎#2 f<int>(const int)代替了f<const int>(const int).这里发生了什么?我的第一个想法是const在函数类型转换中丢弃顶级,因此#2的类型是void(int),这导致了特化f<int>(const int).但我不确定.

为什么C++允许这样的语法?我的意思是因为我们不能部分地专门化函数模板,如果我们想要明确地专门化一个,我们就会知道模板参数值.那么为什么C++不仅仅强制程序员在专门化模板函数时显式提供模板参数值?(即我们必须在#template <> void f<int>(const int) { }或中编写#1的template <> void f<int const>(const int) { }特化)除编码方便外,它是否有特殊用途?

Sam*_*hik 6

void f(const int p)
Run Code Online (Sandbox Code Playgroud)

暂且不考虑模板的问题,const此处的部件没有指定参数的类型f().const这里指定的所有内容pconst在函数内部f().参数的类型f()int.

template <> void f(const int)
Run Code Online (Sandbox Code Playgroud)

当编译器试图推导出特化的类型时,它推断出由于函数参数的类型是int,它必须是一个特化f<int>.

无法以这种方式真正做出演绎工作.你必须明确,如果你想做的话:

template <> void f<const int>(const int) { std::cout << "#2\n"; }
Run Code Online (Sandbox Code Playgroud)