6

From this link here I understand that inorder to pass a lambda we need to pass the method as a parameter and to store it in a std::function type. In such case, is it possible to extract the parameters from a capture list of a lambda?

example

struct foo
{
    std::vector<int> t = {1,2,3};
};

void funct(std::function<void()> func)
{
    func(); //This works fine . Can I extract the object foo from this lambda ?
}

int main()
{
   foo a;
   a.t.push_back(45);
   funct( [a](){ std::cout << "New value is " << a.t[3] ; } );
}
Community
  • 1
  • 1
MistyD
  • 16,373
  • 40
  • 138
  • 240
  • 1
    In order to pass a lambda where? You need what method? I didn't understand any of your introduction. – Barry Mar 16 '16 at 02:39
  • I wanted to know if it was possible to extract the variables embedded inside a lambda type. In my case the variables in func variable – MistyD Mar 16 '16 at 02:41

2 Answers2

3

In order to get access to the object stored in a std::function object, you must use the std::function::target<T> template function. In this case, T is the actual type of the object you passed to the function's constructor.

As it turns out, the type of a lambda is untype-able. That is, the standard requires that, whatever typename the compiler assigns it, it is a typename that you cannot enter on the keyboard. If you don't already have it (either directly or via type deduction on a value of that type), then there's nothing you can do to get it.

Now, you could do this:

template<typename T>
void funct(T func)
{
    std::function<void()> stdfunc(func);

    T *ptr_func = stdfunc.target<T>();
}

Of course, that's rather redundant, since you already have the lambda function's type.

However, even with the above code, you cannot access the capture variables of a lambda. Why? Because the standard doesn't say you can.

The short list of things you're allowed to do with lambda closures:

  • Copy/move construct them, assuming the types captured are copy/moveable.
  • Destroy them.
  • Call them with operator().
  • Convert them to a function pointer, but only if the lambda was capture-less (and non-generic).

The implementation is not required to allow you to access member variables of the lambda. And therefore, there is no standard way to do so. Even if the implementation made them public and named them the way they're named in your code (neither of which is required), the C++ standard does not guarantee that every implementation must do so.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
1

I don't think you can. Because lambdas are equivalent to a class whose operator() has been overloaded. The captured parameters are actually private data members. In this example, your lambda equivalent to:

class _lambda {
  public:
    void operator()() const {
        std::cout << "New value is " << a.t[3];
    }
  private:
    foo a;
}

I don't think you can get access to a private member with friendship ungranted.

Allen Wang
  • 107
  • 1
  • 9
  • The members of the lambda aren't necessarily private - they're just unnamed. – Barry Mar 16 '16 at 02:47
  • @Barry. I don't get it. How can you use unnamed members in operator overloading. Could you please provide some reference? – Allen Wang Mar 16 '16 at 03:03