error: cannot convert ‘<lambda(double)>’ to ‘double (*)(double)’

Viewed 725

I have this error

error: cannot convert ‘<lambda(double)>’ to ‘double (*)(double)’

From the code

void Matrice::mapEmplace(double (*fct)(double))
{
   for (size_t i = 1; i <= nLig; ++i)
      for (size_t j = 1; j <= nCol; ++j)
         (*this)(i, j) = (*fct)((*this)(i, j));
}

--

void function()
{
   // ...
   bool alea = something;

   // alea results on reading in a file
   utilisation.mapEmplace(
      [alea](double x) -> double {
         return alea ? 1 : 0;
      }
   );
   //....
}

When I do not capture alea by declaring it global for example, it works. But when I declare alea in the scope of my function g++ display this error.

Do you know what is the problem and how I can resolve it by keeping alea local to my function?

2 Answers

You can only convert the capture-less lambda to a c-style function pointer. In your case, your lambda capture the alea by copy, and hence the conversion to function pointer type is not possible.

You have two options:

  1. Either use the std::function with some type-eraser overhead.
  2. Or make the function as a templated one, so that the compiler can deduce the type of lambda.
    template<typename T>
    void Matrice::mapEmplace(T fct)
    {
       for (size_t i = 1; i <= nLig; ++i)
           for (size_t j = 1; j <= nCol; ++j)
               (*this)(i, j) = fct((*this)(i, j));
    }
    

std::function is designed expressly to handle a capturing lambda. So, replace this:

void Matrice::mapEmplace(double (*fct)(double)) {
  for(size_t i = 1; i <= nLig; ++i)
    for(size_t j = 1; j <= nCol; ++j)
      (*this)(i,j) = (*fct)((*this)(i,j));
}

with this:

void Matrice::mapEmplace(std::function<double(double)> fct) {
  for(size_t i = 1; i <= nLig; ++i)
    for(size_t j = 1; j <= nCol; ++j)
      (*this)(i,j) = fct((*this)(i,j));
}

And add #include <functional> at the top of your cpp file.

Related