传递给 lambda 的 C++ 绑定函数
C++ bound function passed to a lambda
我在下面的代码中尝试打印 10 的乘法 table。
我用两个参数 5
和 2
绑定了函数 multiply
。我正在传递绑定函数来创建一个 lambda。然后我试图将 lambda 传递给 for_each
循环以打印乘法 Table。我凭直觉知道我可能有点过头了。但我不知道确切的原因。谁能解释一下。
#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
#include <functional>
#include <future>
#include <array>
#include <unistd.h>
using namespace std;
using namespace std::placeholders;
int multiply(int a, int b, int c)
{
return a*b*c;
}
int main()
{
auto f = std::bind(multiply, 5, 2, _1);
std::function<int(int,int,int)> f1 = [f](int a){cout << "Multiplication Table (10) :" << f(a) << endl; };
vector<int> vec = {1,2,3,4,5,6,7,8,9,10};
for_each(vec.begin(), vec.end(), f1);
return 0;
}
我遇到的错误如下所示。
/home/karthik/Workspace/cpppen/learning/main.cpp: In function ‘int main()’:
/home/karthik/Workspace/cpppen/learning/main.cpp:26:107: error: conversion from ‘main()::<lambda(int)>’ to non-scalar type ‘std::function<int(int, int, int)>’ requested
std::function<int(int,int,int)> f1 = [f](int a){cout << "Multiplication Table (10) :" << f(a) << endl;};
^
In file included from /usr/include/c++/7/algorithm:62:0,
from /home/karthik/Workspace/cpppen/learning/main.cpp:6:
/usr/include/c++/7/bits/stl_algo.h: In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Funct = std::function<int(int, int, int)>]’:
/home/karthik/Workspace/cpppen/learning/main.cpp:30:40: required from here
/usr/include/c++/7/bits/stl_algo.h:3884:5: error: no match for call to ‘(std::function<int(int, int, int)>) (int&)’
__f(*__first);
~~~^~~~~~~~~~
In file included from /usr/include/c++/7/functional:58:0,
from /home/karthik/Workspace/cpppen/learning/main.cpp:8:
/usr/include/c++/7/bits/std_function.h:701:5: note: candidate: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = int; _ArgTypes = {int, int, int}]
function<_Res(_ArgTypes...)>::
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
I am passing a function with two bound and one placeholder parameter.
不,你不是。您的 lambda 看起来像这样:
[f](int a) {
cout << "Multiplication Table (10) :" << f(a) << endl;
}
这是您要传递给 std::function
的可调用对象。现在,lambda 只能用一个参数调用,而不是三个。注意:
[/*...*/](int a){ /*...*/ }
// ^^^^^
// one parameter
同样,f
是一个只有一个参数的可调用对象。您不能使用三个参数调用它,因为您已将两个参数绑定到特定值,因此,就所有意图和目的而言,没有三个参数。也许这更清楚:
auto add = [](int a, int b) { return a + b; };
auto addTo5 = [&add](int a) { return add(a, 5); };
add(1, 2); // ok, lambda takes two parameters
addTo5(3); // ok, lambda takes one parameter
addTo5(1, 2); // not ok, lambda doesn't take two parameters
std::function<int(int, int)> fadd = add; // ok
std::function<int(int)> faddTo5 = addTo5; // ok
std::function<int(int, int)> faddTo5fail = addTo5; // not ok, same reason
// addTo5 is approximately what std::bind does: It generates an object which has
// several variables "fixed", and so only takes the placeholder arguments that aren't
// specified.
因此,解决方法是更改 f1
的类型以反映您实际存储的内容;一个不需要 int
和 returns 的可调用对象:
std::function<void(int)> f1 = /*...*/;
// ^^^^
// lambda returns nothing
我在下面的代码中尝试打印 10 的乘法 table。
我用两个参数 5
和 2
绑定了函数 multiply
。我正在传递绑定函数来创建一个 lambda。然后我试图将 lambda 传递给 for_each
循环以打印乘法 Table。我凭直觉知道我可能有点过头了。但我不知道确切的原因。谁能解释一下。
#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
#include <functional>
#include <future>
#include <array>
#include <unistd.h>
using namespace std;
using namespace std::placeholders;
int multiply(int a, int b, int c)
{
return a*b*c;
}
int main()
{
auto f = std::bind(multiply, 5, 2, _1);
std::function<int(int,int,int)> f1 = [f](int a){cout << "Multiplication Table (10) :" << f(a) << endl; };
vector<int> vec = {1,2,3,4,5,6,7,8,9,10};
for_each(vec.begin(), vec.end(), f1);
return 0;
}
我遇到的错误如下所示。
/home/karthik/Workspace/cpppen/learning/main.cpp: In function ‘int main()’:
/home/karthik/Workspace/cpppen/learning/main.cpp:26:107: error: conversion from ‘main()::<lambda(int)>’ to non-scalar type ‘std::function<int(int, int, int)>’ requested
std::function<int(int,int,int)> f1 = [f](int a){cout << "Multiplication Table (10) :" << f(a) << endl;};
^
In file included from /usr/include/c++/7/algorithm:62:0,
from /home/karthik/Workspace/cpppen/learning/main.cpp:6:
/usr/include/c++/7/bits/stl_algo.h: In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; _Funct = std::function<int(int, int, int)>]’:
/home/karthik/Workspace/cpppen/learning/main.cpp:30:40: required from here
/usr/include/c++/7/bits/stl_algo.h:3884:5: error: no match for call to ‘(std::function<int(int, int, int)>) (int&)’
__f(*__first);
~~~^~~~~~~~~~
In file included from /usr/include/c++/7/functional:58:0,
from /home/karthik/Workspace/cpppen/learning/main.cpp:8:
/usr/include/c++/7/bits/std_function.h:701:5: note: candidate: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = int; _ArgTypes = {int, int, int}]
function<_Res(_ArgTypes...)>::
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
I am passing a function with two bound and one placeholder parameter.
不,你不是。您的 lambda 看起来像这样:
[f](int a) {
cout << "Multiplication Table (10) :" << f(a) << endl;
}
这是您要传递给 std::function
的可调用对象。现在,lambda 只能用一个参数调用,而不是三个。注意:
[/*...*/](int a){ /*...*/ }
// ^^^^^
// one parameter
同样,f
是一个只有一个参数的可调用对象。您不能使用三个参数调用它,因为您已将两个参数绑定到特定值,因此,就所有意图和目的而言,没有三个参数。也许这更清楚:
auto add = [](int a, int b) { return a + b; };
auto addTo5 = [&add](int a) { return add(a, 5); };
add(1, 2); // ok, lambda takes two parameters
addTo5(3); // ok, lambda takes one parameter
addTo5(1, 2); // not ok, lambda doesn't take two parameters
std::function<int(int, int)> fadd = add; // ok
std::function<int(int)> faddTo5 = addTo5; // ok
std::function<int(int, int)> faddTo5fail = addTo5; // not ok, same reason
// addTo5 is approximately what std::bind does: It generates an object which has
// several variables "fixed", and so only takes the placeholder arguments that aren't
// specified.
因此,解决方法是更改 f1
的类型以反映您实际存储的内容;一个不需要 int
和 returns 的可调用对象:
std::function<void(int)> f1 = /*...*/;
// ^^^^
// lambda returns nothing