以下代碼中的函數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