EDIT: Sorry, I asked this question without a thro understanding of references...

I seem to be getting this error when I run this code...

error: invalid initialization of non-const reference of type 'std::function&' from an rvalue of type 'main()::'

#include <bits/stdc++.h>
using namespace std ;

void printfunction(bool a, function <void()> &b) 
{ 
    if (a == true) 
    {
        b() ; 
    }
} 

int main() 
{
    int value = 45 ;    

    printfunction(true, [value](){cout << "The value is : " << value ;}) ; 
}

But, the error disappears when I add a const before function... like this :

void printfunction(bool a,const function <void()> &b) 

The thing is I would like to change the function in the function reference if needed... Is there any other way to do this? Please let me know if it does indeed exist.

Bye,

Samuel

2

There are 2 answers

0
Maxim Egorushkin On BEST ANSWER

In printfunction call, lambda expression [value]() {...} argument must be converted to a temporary function<void()> object first.

A reference to non-const function<void()>& only binds to l-values, not temporaries (r-values).

A reference to const, on the other hand, can be bound to temporaries. Which is what you observe.

0
Toby Speight On

If you want to modify the std::function, then you'll need to pass a modifiable (lvalue) parameter:

int main()
{
    int value = 45;

    std::function f = [value](){ std::cout << "The value is : " << value ;};

    printfunction(true, f);
}

What you were trying to do isn't much different from writing a function that takes a mutable reference to int (e.g. void foo(int& x)) and then complaining that you can't call foo(5). (The small difference is that the the lambda-expression is converted to a temporary std::function - but that still can't be bound to a non-const reference).


An alternative would be to change printfunction to take its argument by value rather than by reference, so that it has its own copy which it may modify. You'll have to consider the needs of the caller to decide whether that's more appropriate.