以下代码中的函数invoke
是调用另一个函数/函数/ lambda的简单包装,因此invoke(f,args...)
等于f(args...)
。 (这背后的原因是也有成员函数过载,从而允许这两种用法的一般化的语法。)从仿函数模板参数中推导可变参数和返回类型(特定于MSVC)
此实现工作在克++:
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(十一月CTP)抱怨:
Error: C2893: Failed to specialize function template 'unknown-type invoke(Fn,Args...)'
With the following template arguments:
'main::<lambda_687537b292ffb7afcfd8f8fc292d6e73>'
'int'
(请注意,在错误信息的int
来自42
被传递给invoke
,而不是来自lambda的论点。我通过传递与invoke
不同的东西来检查此问题。)
我该如何解决这个问题以便与MSVC 2012(Nov CTP)一起使用?
的资料我尝试:
当我改变可变参数模板参数的单个参数(但仍然是一个模板参数,即除去在上面的代码中的所有
...
),代码编译。但我需要支持任何数量的参数。它还编译,如果我用非通用的
int
返回类型替换尾随返回类型。但显然我想支持泛型返回类型。如果我传递函数指针而不是lambda表达式,行为不会改变。所以它与lambda无关。例如错误消息:
Error: C2893: Failed to specialize function template 'unknown-type invoke(Fn,Args...)' With the following template arguments: 'int (__cdecl *)(int)' 'double'
在Visual Studio 2013中实现了可变参数模板。请参阅[Support for C++ 11 Features](http://msdn.microsoft.com/zh-cn/library/hh567368.aspx) – 2014-09-24 00:49:04
“'invoke(f, args ...)'等于'f(args ...)'“。对于当前定义的'invoke','invoke(f,std :: move(x))'不等于'f(std :: move(x))'。您需要通过使用通用/转发引用和“std :: forward”来转发参数。 – 2014-09-24 00:51:41
@JonathanPotter他们已被添加到MSVC 2012年11月CTP补丁 – leemes 2014-09-24 00:51:43