使用 std::function 和 bind 来分配具有不同参数列表的函数
Using std::function and bind to assign functions with different argument lists
我正在尝试拥有一个函数指针,在某些情况下,它要么被分配一个接受 2 个参数的函数(一个 cv::Mat 和一个包含参数的结构),要么被分配一个不同的函数接受3 个参数(相同的 2 个参数和一个坐标列表)。我认为 std::function 和 std::bind 是我应该在这里使用的。
Mat process_F1(cv::Mat img, feature_params f);
Mat process_F1_coords(cv::Mat img, feature_params f, std::vector<std::pair<int, int> > feature_coords c);
Mat process_F2(cv::Mat img, feature_params f);
Mat process_F2_coords(cv::Mat img, feature_params f, std::vector<std::pair<int, int> > feature_coords );
// this is the function pointer that will hold them
std::function<cv::Mat()> feature_func_f;
//this is how I assign them:
void set_feature_func(int feature_method, bool use_coords)
{
switch (feature_method){
case 0:
if( !use_coords )
feature_func_f = std::bind(process_F1,std::placeholders::_2);
else
feature_func_f = std::bind(process_F1_coords,std::placeholders::_3);
break;
case 1:
if( !use_coords )
feature_func_f = std::bind(process_F2,std::placeholders::_2);
else
feature_func_f = std::bind(process_F2_coords,std::placeholders::_3);
break;
}
我打算将 feature_func_f 称为:
cv::Mat m, n;
feature_params p;
set_feature_func(0,false);
n = feature_func_f(m,p);
// or if I have a coordinate list c
std::vector<std::pair<int, int> > c;
set_feature_func(0,true);
n = feature_func_f(m,p,c);
我在这里做错了什么?我收到一堆错误,这些错误在 header 中对函数式没有真正意义:
Error 4 error C2977: 'std::add_reference' : too many template arguments C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 5 error C2955: 'std::add_reference' : use of class template requires template argument list C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 6 error C2198: 'cv::Mat (__cdecl *)(cv::Mat,feature_params)' : too few arguments for call C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 1149 1
Error 2 error C2146: syntax error : missing ',' before identifier 'type' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 3 error C2065: 'type' : undeclared identifier C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 1 error C2027: use of undefined type 'std::tuple_element<0x01,_Ftuple>' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
不,你不能做你想做的事。 std::bind
仅用于绑定参数,不应在函数调用中使用。您可以使用 2 个函数,一个用于 2 个参数,一个用于 3 个参数,或者将坐标发送到函数 set_feature_func
.
关于 std::function
和 std::bind
用法的简单示例。
#include <functional>
#include <iostream>
int main()
{
std::function<void(int)> function;
auto l1 = [](int v) { std::cout << v << std::endl; };
auto l2 = [](int v1, int v2) { std::cout << v1 << " " << v2 << std::endl; };
function = l1;
function(5);
function = std::bind(l2, std::placeholders::_1, 10);
function(5);
}
你的代码应该是这样的
std::function<cv::Mat(cv::Mat, feature_params)> feature_func_f;
// coords is vector<vector<...>>
void set_feature_func(int feature_method, coords)
{
// switch
if (coords.empty())
{
feature_func_f = process_f1;
}
else
{
feature_func_f = std::bind(process_f1, _1, _2, coords);
}
}
用法
std::vector<std::pair<int, int> > c;
set_feature_func(0,true,c);
n = feature_func_f(m,p);
一般来说,变量的类型决定了您可以对变量进行何种操作。
feature_func_f
有一种类型。先前的函数调用无法更改其类型。
std::function
支持 one 参数签名。
因此 n = feature_func_f(m,p);
和 n = feature_func_f(m,p,c);
不能在 std::function
上都有效。
有很多方法可以解决这个问题,但在这种情况下没有多大意义。有两个 feature_func_f
,每个都有不同的签名,并调用正确的那个。
std::function<cv::Mat(cv::Mat img, feature_params f)> feature_func_f;
std::function<cv::Mat(cv::Mat img, feature_params f, std::vector<std::pair<int,int>>)> feature_func_vector_f;
我正在尝试拥有一个函数指针,在某些情况下,它要么被分配一个接受 2 个参数的函数(一个 cv::Mat 和一个包含参数的结构),要么被分配一个不同的函数接受3 个参数(相同的 2 个参数和一个坐标列表)。我认为 std::function 和 std::bind 是我应该在这里使用的。
Mat process_F1(cv::Mat img, feature_params f);
Mat process_F1_coords(cv::Mat img, feature_params f, std::vector<std::pair<int, int> > feature_coords c);
Mat process_F2(cv::Mat img, feature_params f);
Mat process_F2_coords(cv::Mat img, feature_params f, std::vector<std::pair<int, int> > feature_coords );
// this is the function pointer that will hold them
std::function<cv::Mat()> feature_func_f;
//this is how I assign them:
void set_feature_func(int feature_method, bool use_coords)
{
switch (feature_method){
case 0:
if( !use_coords )
feature_func_f = std::bind(process_F1,std::placeholders::_2);
else
feature_func_f = std::bind(process_F1_coords,std::placeholders::_3);
break;
case 1:
if( !use_coords )
feature_func_f = std::bind(process_F2,std::placeholders::_2);
else
feature_func_f = std::bind(process_F2_coords,std::placeholders::_3);
break;
}
我打算将 feature_func_f 称为:
cv::Mat m, n;
feature_params p;
set_feature_func(0,false);
n = feature_func_f(m,p);
// or if I have a coordinate list c
std::vector<std::pair<int, int> > c;
set_feature_func(0,true);
n = feature_func_f(m,p,c);
我在这里做错了什么?我收到一堆错误,这些错误在 header 中对函数式没有真正意义:
Error 4 error C2977: 'std::add_reference' : too many template arguments C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 5 error C2955: 'std::add_reference' : use of class template requires template argument list C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 6 error C2198: 'cv::Mat (__cdecl *)(cv::Mat,feature_params)' : too few arguments for call C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 1149 1
Error 2 error C2146: syntax error : missing ',' before identifier 'type' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 3 error C2065: 'type' : undeclared identifier C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
Error 1 error C2027: use of undefined type 'std::tuple_element<0x01,_Ftuple>' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\functional 900 1
不,你不能做你想做的事。 std::bind
仅用于绑定参数,不应在函数调用中使用。您可以使用 2 个函数,一个用于 2 个参数,一个用于 3 个参数,或者将坐标发送到函数 set_feature_func
.
关于 std::function
和 std::bind
用法的简单示例。
#include <functional>
#include <iostream>
int main()
{
std::function<void(int)> function;
auto l1 = [](int v) { std::cout << v << std::endl; };
auto l2 = [](int v1, int v2) { std::cout << v1 << " " << v2 << std::endl; };
function = l1;
function(5);
function = std::bind(l2, std::placeholders::_1, 10);
function(5);
}
你的代码应该是这样的
std::function<cv::Mat(cv::Mat, feature_params)> feature_func_f;
// coords is vector<vector<...>>
void set_feature_func(int feature_method, coords)
{
// switch
if (coords.empty())
{
feature_func_f = process_f1;
}
else
{
feature_func_f = std::bind(process_f1, _1, _2, coords);
}
}
用法
std::vector<std::pair<int, int> > c;
set_feature_func(0,true,c);
n = feature_func_f(m,p);
一般来说,变量的类型决定了您可以对变量进行何种操作。
feature_func_f
有一种类型。先前的函数调用无法更改其类型。
std::function
支持 one 参数签名。
因此 n = feature_func_f(m,p);
和 n = feature_func_f(m,p,c);
不能在 std::function
上都有效。
有很多方法可以解决这个问题,但在这种情况下没有多大意义。有两个 feature_func_f
,每个都有不同的签名,并调用正确的那个。
std::function<cv::Mat(cv::Mat img, feature_params f)> feature_func_f;
std::function<cv::Mat(cv::Mat img, feature_params f, std::vector<std::pair<int,int>>)> feature_func_vector_f;