问题
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
Demo
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'
回答1:
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.
来源:https://stackoverflow.com/questions/26006750/deduce-variadic-args-and-return-type-from-functor-template-parameter-msvc-speci