How to Make a helper function which accepts a lambda in C++

Advertisements

Right now I have a function which makes some changes in an array of uchar (will act as a LUT) so I can decide which transformation will be implemented on that LUT.

for (size_t i = 0; i <= 255; ++i)
{
    lut_transform[0].at<uchar>(i) = 255-i; //Inverse function
}
for (size_t i = 0; i <= 255; ++i)
{
    lut_transform[1].at<uchar>(i) = pow((float)i * 255,(1/2.0)); //Square Root function
}
for (size_t i = 0; i <= 255; ++i)
{
    lut_transform[2].at<uchar>(i) = pow((float)i, 3.0) / (255*255); //Cubic function
}

So I want to improve this and create a helper function which receives as a parameter the array and the function algorithm to implement. So should look something like this.

void transform_function_helper (std::vector<uchar>& vec_tf, lambda_arg f(int)){
  for (int i = 0; i < vec_tf.size(); ++i) {
    vec_tf.at<uchar>(i) = f(i);
  }
}
void current_function_already_working(){
  /* code */
  //replacing the 3 for for the calls to the helper function
  //lut_transform is a vector of uchar vector
  transform_function_helper(lut_transform[0], [](const int x) -> uchar { 255 - x; } );
  transform_function_helper(lut_transform[1], [](const int x) -> uchar { pow((float)x * 255,(1/2.0)); } );
  transform_function_helper(lut_transform[2], [](const int x) -> uchar { pow((float)x, 3.0) / (255*255); } );
  /*code*/
}

I hope this is clear.

>Solution :

You have three choices:

  1. use a plain C-style function pointer (since you are not using any capturing lambdas), eg:
void transform_function_helper (std::vector<uchar>& vec_tf, uchar (*f)(size_t)) {
  for (size_t i = 0; i < vec_tf.size(); ++i) {
    vec_tf[i] = f(i);
  }

  /* alternatively:
  size_t i = 0;
  for (auto &elem : vec_tf) {
    elem = f(i++);
  }
  */
}
  1. Use std::function, eg:
#include <functional>

void transform_function_helper (std::vector<uchar>& vec_tf, std::function<uchar(size_t)> f) {
  for (size_t i = 0; i < vec_tf.size(); ++i) {
    vec_tf[i] = f(i);
  }

  /* alternatively:
  size_t i = 0;
  for (auto &elem : vec_tf) {
    elem = f(i++);
  }
  */
}
  1. Use a template function, eg:
template<typename Callable>
void transform_function_helper (std::vector<uchar>& vec_tf, Callable f) {
  for (size_t i = 0; i < vec_tf.size(); ++i) {
    vec_tf[i] = f(i);
  }

  /* alternatively:
  size_t i = 0;
  for (auto &elem : vec_tf) {
    elem = f(i++);
  }
  */
}

Either way, you can then call the helper function like this:

void current_function_already_working(){
  /* code */
  //replacing the 3 for for the calls to the helper function
  //lut_transform is a vector of uchar vector
  transform_function_helper(lut_transform[0], [](size_t x) -> uchar { return 255 - x; } );
  transform_function_helper(lut_transform[1], [](size_t x) -> uchar { return pow((float)x * 255,(1/2.0)); } );
  transform_function_helper(lut_transform[2], [](size_t x) -> uchar { return pow((float)x, 3.0) / (255*255); } );
  /*code*/
}

Leave a Reply Cancel reply