从函子模板参数(MSVC特定)中减去可变参数和返回类型 [英] Deduce variadic args and return type from functor template parameter (MSVC-specific)
问题描述
下面代码中的函数 invoke
是调用另一个函数/ functor / lambda的简单包装,使得 invoke(f,args。 ..)
equals f(args ...)
。 (这个的原因是成员函数也有重载,允许两种用法的通用语法。)
这个实现在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
但是,MSVC 2012(11月CTP)抱怨:
< =lang-none prettyprint-override>
错误:C2893:无法专门化函数模板'unknown-type invoke(Fn,Args ...)'
使用以下模板参数:
'main ::< lambda_687537b292ffb7afcfd8f8fc292d6e73>'
'int'
错误消息中的 int
来自传递给 invoke $的
42
c $ c>,而不是lambda的参数。我通过传递不同于 invoke
的东西来检查这个。)
我如何解决这个问题与MSVC 2012(11月CTP)?
我试过的东西:
-
当我将可变参数模板参数更改为单个参数(但仍然是模板参数,即在上面的代码中删除所有
...
),代码编译。但是我需要支持任何数量的参数。 -
如果我用非泛型
int
返回类型。但是显然我想支持通用返回类型。 -
如果我传递一个函数指针而不是一个lambda,行为不会改变。所以它不与lambdas相关。示例错误消息:
错误:C2893:无法专门化函数模板未知类型invoke Fn,Args ...)'
使用以下模板参数:
'int(__cdecl *)(int)'
'double'
尝试使用 typename result_of< ; F(Args ...)> :: type
。 (我的意思是:使用类型不是值)。
这不支持SFINAE在标准下,但如果可能工作在一半兼容的C ++ 11编译器
还可以使用 Args&& ...
,如果你的编译器没有爆炸, / p>
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'
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.
这篇关于从函子模板参数(MSVC特定)中减去可变参数和返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!