请您解释一下,为什么显式模板实例化在这里不起作用?
template <typename T>
bool IsEqual(T v1, T v2) {
return v1 == v2;
}
template bool IsEqual<double>(double a, double b);
int main() {
int c = 4;
double d = 4.0;
IsEqual(c,d)
return 0;
}
代码产生的错误是:
note: template argument deduction/substitution failed:
note: deduced conflicting types for parameter 'T' ('int' and 'double')
如果函数不是模板函数,那么一切都运行良好。所以我期望一个显式的实例化来创建相同的函数。
bool IsEqualT (double a, double b) {
return a == b;
}
答案 0 :(得分:3)
模板参数推导不会关注显式实例化或重载解析。
如果要调用IsEqual
或将其声明更改为
template <typename T, typename S>
bool IsEqual(T v1, S v2) {
return v1 == v2;
}
// ... main
int c = 4;
double d = 4.0;
printf("%s", IsEqual(c,d) == true ? "True" : "False"); // Prints true
或帮助编译器通过将T
指定为double
来选择正确的重载。
IsEqual<double>(c,d);
答案 1 :(得分:3)
手动标记
template bool IsEqual<double>(double a, double b)
不会阻止编译器在
中进行模板参数推断IsEqual(c,d)
它只是告诉编译器,不管它可能标记出哪些其他函数,你希望它为double
s标记该函数。
因此,由于您仍然经历模板参数推导,int
与double
不同,您会收到编译器错误。您将要么必须将c
转换为double,要么重写该函数以获得2个模板参数,因此它可以采用两种不同的类型。
答案 2 :(得分:2)
显式模板实例化保证编译器为特定的模板参数集生成代码,这意味着如果链接器需要它,将会找到它。
它不会隐藏模板参数的其他组合,或阻止它们被实例化(隐式或其他方式)。
因此,显式实例化对模板参数推导没有影响,对重载决策没有影响。整个可能的实例化家庭仍然是候选人。