問題描述
基本上,我希望能夠做的是使用任意數量的任意類型參數的 lambda 并將其轉換為 std::function.我嘗試了以下方法,但都不起作用.
Basically, what I want to be able to do is take a lambda with any number of any type of parameters and convert it to an std::function. I've tried the following and neither method works.
std::function([](){});//Complains that std::function is missing template parameters
template <typename T> void foo(function<T> f){}
foo([](){});//Complains that it cannot find a matching candidate
然而,以下代碼確實有效,但這不是我想要的,因為它需要明確聲明模板參數,這不適用于通用代碼.
The following code does work however, but it is not what I want because it requires explicitly stating the template parameters which does not work for generic code.
std::function<void()>([](){});
我整個晚上都在處理函數和模板,但我無法弄清楚,因此非常感謝您的幫助.
I've been mucking around with functions and templates all evening and I just can't figure this out, so any help would be much appreciated.
正如評論中提到的,我嘗試這樣做的原因是因為我試圖使用可變參數模板在 C++ 中實現柯里化.不幸的是,這在使用 lambda 時會失敗.例如,我可以使用函數指針傳遞一個標準函數.
As mentioned in a comment, the reason I'm trying to do this is because I'm trying to implement currying in C++ using variadic templates. Unfortunately, this fails horribly when using lambdas. For example, I can pass a standard function using a function pointer.
template <typename R, typename...A>
void foo(R (*f)(A...)) {}
void bar() {}
int main() {
foo(bar);
}
但是,我不知道如何將 lambda 傳遞給這樣的可變參數函數.為什么我對將泛型 lambda 轉換為 std::function 感興趣是因為我可以執行以下操作,但最終要求我將模板參數顯式聲明為 std::function,這是我試圖避免的.
However, I can't figure out how to pass a lambda to such a variadic function. Why I'm interested in converting a generic lambda into an std::function is because I can do the following, but it ends up requiring that I explicitly state the template parameters to std::function which is what I am trying to avoid.
template <typename R, typename...A>
void foo(std::function<R(A...)>) {}
int main() {
foo(std::function<void()>([](){}));
}
推薦答案
你不能在沒有明確指定模板的情況下將 lambda 函數對象作為 std::function
類型的參數傳遞參數 T
.模板類型推導嘗試將您的 lambda 函數的類型與 std::function
匹配,在這種情況下它無法做到 - 這些類型不相同.模板類型推導不考慮類型之間的轉換.
You can't pass a lambda function object as an argument of type std::function<T>
without explicitly specifying the template argument T
. Template type deduction tries to match the type of your lambda function to the std::function<T>
which it just can't do in this case - these types are not the same. Template type deduction doesn't consider conversions between types.
如果你能給它一些其他的方式來推斷類型,這是可能的.您可以通過將函數參數包裝在 identity
類型中來做到這一點,這樣它就不會在嘗試將 lambda 與 std::function
匹配時失敗(因為依賴類型是只是被類型推導忽略了)并給出了一些其他參數.
It is possible if you can give it some other way to deduce the type. You can do this by wrapping the function argument in an identity
type so that it doesn't fail on trying to match the lambda to std::function
(because dependent types are just ignored by type deduction) and giving some other arguments.
template <typename T>
struct identity
{
typedef T type;
};
template <typename... T>
void func(typename identity<std::function<void(T...)>>::type f, T... values) {
f(values...);
}
int main() {
func([](int x, int y, int z) { std::cout << (x*y*z) << std::endl; }, 3, 6, 8);
return 0;
}
這顯然在您的情況下沒有用,因為您不想在以后傳遞值.
This is obviously not useful in your situation though because you don't want to pass the values until later.
由于您不想指定模板參數,也不想傳遞可以從中推斷出模板參數的其他參數,因此編譯器將無法推斷出您的 std 的類型::function
參數.
Since you don't want to specify the template parameters, nor do you want to pass other arguments from which the template parameters can be deduced, the compiler won't be able to deduce the type of your std::function
argument.
這篇關于如何使用模板將 lambda 轉換為 std::function的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!