Konstantin
Konstantin

Reputation: 3159

Why the explicit template instantiation doesn't work

Could you please explain, why the explicit template instantiation doesn't work here?

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

The error the code produces is:

note:   template argument deduction/substitution failed:
note:   deduced conflicting types for parameter 'T' ('int' and 'double')

If the function isn't a template function then everything works well. So I expect an explicit instantiation to create the same function.

bool IsEqualT (double a, double b) {
    return a == b;
}

Upvotes: 0

Views: 385

Answers (3)

kocica
kocica

Reputation: 6465

Template parameter deduction doesnt take care about explicit instantiation or overload resolution.

You have to pass arguments of same type if you want to call IsEqual or change its declaration to

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

or help compiler choose right overload by specifing T as double.

IsEqual<double>(c,d);

Upvotes: 3

NathanOliver
NathanOliver

Reputation: 181068

Manually stamping out

template bool IsEqual<double>(double a, double b)

Doesn't stop the compiler from doing template argument deduction in

IsEqual(c,d)

It just tells the compiler regardless of what other functions it might stamp out, you want it to stamp out that function for doubles.

So, since you still go through template argument deduction, and int is not the same as double you get the compiler error. You will either have to cast c to a double or rewrite the function to have 2 template parameters so it can take two different types.

Upvotes: 3

Ben Voigt
Ben Voigt

Reputation: 283971

An explicit template instantiation guarantees that the compiler produces code for a particular set of template parameters, which means it will be found if the linker needs it.

It doesn't hide other combinations of template parameters, or prevent them from being instantiated (implicitly or otherwise).

As such, explicit instantiation has no effect on template parameter deduction, and no effect on overload resolution. The whole family of possible instantiation are still candidates.

Upvotes: 2

Related Questions