使用std::function和bind为具有不同参数列表的函数赋值

Using std::function and bind to assign functions with different argument lists

本文关键字:参数 列表 函数 赋值 function std bind 使用      更新时间:2023-10-16

我试图有一个函数指针,在某些情况下,它被分配一个函数需要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);

我在这里做错了什么?我得到了一堆错误,这些错误在function:

的标题中没有真正的意义
Error   4   error C2977: 'std::add_reference' : too many template arguments C:Program Files (x86)Microsoft Visual Studio 12.0VCincludefunctional   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.0VCincludefunctional   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.0VCincludefunctional   1149    1   
Error   2   error C2146: syntax error : missing ',' before identifier 'type'    C:Program Files (x86)Microsoft Visual Studio 12.0VCincludefunctional   900 1   
Error   3   error C2065: 'type' : undeclared identifier C:Program Files (x86)Microsoft Visual Studio 12.0VCincludefunctional   900 1   
Error   1   error C2027: use of undefined type 'std::tuple_element<0x01,_Ftuple>'   C:Program Files (x86)Microsoft Visual Studio 12.0VCincludefunctional   900 1   

不行,你不能随心所欲。std::bind只是用于绑定参数,不应该在函数调用中使用。您可以使用2个函数,一个为2参数,一个为3参数,或发送坐标到功能set_feature_func

仅举std::functionstd::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支持一个参数签名

因此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;