Reputation: 45675
The function invoke
in the following code is a simple wrapper for invoking another function / functor / lambda, such that invoke(f,args...)
equals f(args...)
. (The reason behind this is to also have overloads for member functions, allowing a generalized syntax for both usages.)
This implementation works in g++:
template <class Fn, class ...Args>
auto invoke(Fn f, Args ...args) -> decltype(f(args...)) {
return f(args...);
}
int y = invoke([](int x){ return x+1; }, 42); // y = 43
However, MSVC 2012 (Nov CTP) complains:
Error: C2893: Failed to specialize function template 'unknown-type invoke(Fn,Args...)'
With the following template arguments:
'main::<lambda_687537b292ffb7afcfd8f8fc292d6e73>'
'int'
(Note that the int
in the error message comes from the 42
being passed to invoke
, not from the lambda's argument. I checked this by passing something different to invoke
.)
How can I fix this to work with MSVC 2012 (Nov CTP)?
Things I tried:
When I change the variadic template arguments to a single argument (but still a template argument, i.e. remove all ...
in the code above), the code compiles. But I need to Support any number of arguments.
It also compiles if I replace the trailing return type with a non-generic int
return type. But obviously I want to support generic return types.
The behavior doesn't change if I pass a function pointer instead of a lambda. So it isn't related to lambdas. Example error message:
Error: C2893: Failed to specialize function template 'unknown-type invoke(Fn,Args...)'
With the following template arguments:
'int (__cdecl *)(int)'
'double'
Upvotes: 2
Views: 814
Reputation: 275405
Try using typename result_of<F(Args...)>::type
. (and I do mean the case: use types not values).
This does not support SFINAE under the standard, but if might work in half compliant C++11 compilers.
Also use Args&&...
and perfect forward if your compiler does not blow up.
Upvotes: 2