1

I am trying to use a lambda with state as a function pointer parameter, state here meaning that it captures from it's context. According to this issue that's not legal: Why does the implicit "lambda to function pointer conversion" forbid the "by reference" capture of static members?

Current function I want to pass the lambda to: void foo( void( func* )( unsigned long ) )

This is a simplified version of where I'm creating the lambda I want to pass:

void MyClass::myClassFunc( int a, int b, int c )
{
    auto myLambda = [&]( unsigned long val ){ a+=val;b+=val;c+=val; };
    foo( /*some magic conversion*/ myLambda );
}

Easy solution, overload foo: void foo( std::function< void( unsigned long ) > func )

The easy solution is undesirable because it requires me to modify code that isn't mine. Is there a way that I can somehow convert the lambda only in calling code?

Community
  • 1
  • 1
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 2
    Why is `std::function` "discouraged"? It's the easiest way to accept arbitrary function types. (Alternatively, you could make whatever uses the functor a template parametrised by the functor type; that would avoid any overhead there might be in creating a `std::function`). – Mike Seymour Feb 26 '14 at 12:03
  • Can you capture the problem data by value? – Adam Burry Feb 26 '14 at 12:04
  • 1
    @AdamBurry: You can't convert a lambda to a function pointer if it captures anything, whether by value or reference. – Mike Seymour Feb 26 '14 at 12:05
  • @MikeSeymour, Thanks. I did not get the question at first. Now I see what is being asked. – Adam Burry Feb 26 '14 at 12:08
  • @MikeSeymour By "discouraged" I mean it's not my code, I can mess with it, but my preference is to make all the changes in my code. So as far as tempting or overloading the function I'm trying to call... that's "discouraged". I'll try to update the question to make it clearer. – Jonathan Mee Feb 26 '14 at 12:29
  • Just write a wrapper. – cqdjyy01234 Feb 27 '14 at 01:20
  • @user1535111 sounds like you have the information that I want... You are suggesting that I can write a "wrapper" and pass my wrapped lambda into: `void foo( void( func* )( unsigned long ) )`? If so I'd really like if you could post an answer explaining how one would write said wrapper. – Jonathan Mee Feb 27 '14 at 12:56
  • @JonathanMee Sorry, but when I start writing code, I find it seems impossible. Because a wrapper must be of type func, I return to the problem: convert a lambda to a func. – cqdjyy01234 Feb 27 '14 at 13:10
  • If your program is single threaded, you may use a global pointer and change the pointer to the current state. Since the pointer is global, you can write a wrapper easily. Because a func is an ordinary function pointer, if the pointer has any states, it must have static storage. – cqdjyy01234 Feb 27 '14 at 14:32
  • @user1535111 I follow what you're saying except about "change the pointer to the current state" A global pointer would not have visibility into the variables and parameters of an instance of `MyClass`'s call to `myClassFunc`. – Jonathan Mee Feb 27 '14 at 14:37
  • Props to @user1535111 who linked [this](http://stackoverflow.com/questions/7852101/c-lambda-with-captures-as-a-function-pointer?rq=1%3E) in his now defunct answer. It would appear that there isn't a great answer to the problem, and as good as I can do is to simply using the "Easy solution" mentioned in the question. – Jonathan Mee Feb 27 '14 at 15:47

1 Answers1

1

Yes, accept the lambda by reference. Since you can't name its type, you'll need a function template.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
MSalters
  • 173,980
  • 10
  • 155
  • 350