I have a template that works if I pass it one lambda, but in a related template that takes two lambdas mapped to the same templated type, it cannot deduce that type, and MSVC++ Express 2013 complains the template parameter is ambiguous. To be clear up front, there is no overloading (or specialization) going on here -- my two examples below are the only entities with those identifiers. Here are the templates, which simply apply the callable objects on an argument and return a result:
template <class A, class OP>
auto WhichOp1(A argument, OP firstOp)->decltype(firstOp(argument)) {
return firstOp(argument);
}
template <class A, class OP>
auto WhichOp2(A argument, OP firstOp, OP secondOp)->decltype(firstOp(argument)) {
return firstOp(argument) + secondOp(argument);
}
I can use WhichOp1 successfully like so:
int e = WhichOp1(2, [](int i){return i * 2; });
But a similar call to WhichOp2 won't compile:
int d = WhichOp2(2, [](int i){return i * 2; }, [](int i){return i * 3; });
I get the following errors:
error C2782: 'unknown-type chaj::ops::WhichOp2(A,OP,OP)' : template parameter 'OP' is ambiguous
IntelliSense: no instance of function template "chaj::ops::WhichOp2" matches the argument list argument types are: (int, lambda []int (int i)->int, lambda []int (int i)->int)
What I gather is that it simply can't take the first lambda with the second one and determine between the two what exactly OP's type should be. If I explicitly instantiate, it works fine to resolve the ambiguity:
int b = WhichOp2<int, int(*)(int)>(2, [](int i){return i * 2; }, [](int i){return i * 3; });
So my question is simply an attempt to have a better understanding of what is going on -- why can the compiler not resolve ambiguity when passing two similar lambdas to a template under a common template parameter? The intellisense error seems to map the type of the lambdas to the same type. I won't be surprised if this is compiler specific, but if anyone sees that this works on their compiler, I'd be interested to know.