C++ Function Template instantiaion with implicit parameters

c++, compiler-errors, function-templates

Solution

In the first one, the compiler knows that `A` is `int` because you specifically tell it so with `foo<int>`, and it knows that `B` is also `int` because of the parameter that you pass it. So both `A` and `B` are known or can be deduced (you could say: `A` is supplied, `B` is implied).

However, in the second one, since `B` comes first and `A` doesn't appear in the parameter list, the compiler can't tell what `A` is and gives you an error. You're explicitly telling it what `B` is with `foo<int>`, and then the parameter you pass is also a `B` which, at the call, is an `int` which agrees with your previous explicit definition of `B`, but no mention is made of `A`, implicitly or explicitly, so the compiler must stop and error.

You don't really need the standard for this, it's just common sense. What on earth would `A` be in the second one?

Thanks for asking this question though, because I didn't realise you could explicitly specify some parameters and implicitly specify others in the parameter list before this.

Problem

I can't figure out why the following code compiles fine: ``` #include <iostream> void bar(int x) { std::cout << "int " << x << std::endl; } void bar(double x) { std::cout << "double " << x << std::endl; } template <typename A, typename B> // Note the order of A and B. void foo(B x) { bar((A)x); } int main() { int x = 1; double y = 2; foo<int>(x); // Compiles OK. foo<double>(y); // Compiles OK. return 0; } ``` But if I switch the order of `A` and `B` as below, then it won't compile: ``` #include <iostream> void bar(int x) { std::cout << "int " << x << std::endl; } void bar(double x) { std::cout << "double " << x << std::endl; } template <typename B, typename A> // Order of A and B are switched. void foo(B x) { bar((A)x); } int main() { int x = 1; double y = 2; foo<int>(x); // error: no matching function for call to ‘foo(int&)’ foo<double>(y); // error: no matching function for call to ‘foo(double&)’ return 0; } ``` EDIT: Ad-hoc explanations are welcome, but would be better if someone can point out exact what the spec. says. Thanks!

Original source