这个主题看起来有点混乱,但我不知道如何更好地表达它,抱歉=)
让我们看一下以下代码:
#include <iostream>
template<typename T>
void f(T value) {
std::cout << "f<T>" << std::endl;
}
template<>
void f(int value) {
std::cout << "f<int>" << std::endl;
}
template<typename T>
struct S {
using type = T;
};
template<typename T>
void f(typename S<T>::type value) {
std::cout << "f<S<T>>" << std::endl;
};
int main() {
f(123);
f<int>(123);
}
输出结果为:
$ ./testgcc
f<int>
f<S<T>>
那么问题是为什么第一次调用会导致
f<int>
的特化,而第二次使用显式的 int 模板参数则导致调用“有模板的”f<S<int>>()
?在标准中是否有规定如何在这种情况下实例化模板?提前感谢!
PS:在不同版本的gcc和clang上进行了测试-行为相同。我没有Windows系统来测试MSVC,但我在godbolt上测试了MSVC在以下代码中的结果:
_main PROC
; ....
push 123 ; 0000007bH
call void f<int>(int) ; f<int>
add esp, 4
push 123 ; 0000007bH
call void f<int>(int) ; f<int>
; ...
因此,无论哪种情况下 MSVC 都会调用 f<int>
。这种行为是否被记录为“实现定义”?
int
不应该使用 S<T> 版本,那么哪些类型应该使用呢?你如何决定? - Jerry Jeremiah