2

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?

JeJo
  • 30,635
  • 6
  • 49
  • 88
Sevla
  • 67
  • 1
  • 10

2 Answers2

4

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));
    }
    
JeJo
  • 30,635
  • 6
  • 49
  • 88
3

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.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • 1
    `std::function` is a rather heavyweight option. In general, it has to allocate memory to hold the function object. In this case, the captured object is a bool and will fit inside the small buffer optimization. However, I would probably go for the template in this case. – Justin Jun 12 '20 at 22:43
  • @Paul Sanders It works perfectly thanks. – Sevla Jun 12 '20 at 22:53