为什么显式模板实例化不起作用

时间:2017-08-25 18:34:20

标签: c++ templates

请您解释一下,为什么显式模板实例化在这里不起作用?

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;
}

3 个答案:

答案 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标记该函数。

因此,由于您仍然经历模板参数推导,intdouble不同,您会收到编译器错误。您将要么必须将c转换为double,要么重写该函数以获得2个模板参数,因此它可以采用两种不同的类型。

答案 2 :(得分:2)

显式模板实例化保证编译器为特定的模板参数集生成代码,这意味着如果链接器需要它,将会找到它。

它不会隐藏模板参数的其他组合,或阻止它们被实例化(隐式或其他方式)。

因此,显式实例化对模板参数推导没有影响,对重载决策没有影响。整个可能的实例化家庭仍然是候选人。