2

I am using Visual Studio 2015. My problem is when I run this it compiles and runs no problem:

typedef double Fct(double);

struct Function {
    Function(Fct f) { cout << f(1) << endl; };
 };

double double_func(double x, double n) { return x + n; }

int main() {
   for(int n = 0; n < 50; ++n)
      Function e{ [](double x) { return double_func(x,1); } }
}

The thing is I want to have this part:

Function e{ [](double x) { return double_func(x,1); } }

To have a capture argument like this:

typedef double Fct(double);

struct Function {
    Function(Fct f) {};
 };

double double_func(double x, double n) { return x + n; }

int main() {
   for(int n = 0; n < 50; ++n)
      Function e{ [n](double x) { return double_func(x,n); } }
}

But I get this error: no instance of constructor "Function::Function" matches the argument list argument types are: (lambda []double (double x)->double)

1

2 Answers 2

3

Edit: Removed Example 1. Doesn't work anymore. :(

Lambdas are actually more a class with a operator() implemented. If you want to save a captured one, you have to store it as an object function pointer:

int first = 5;
auto lambda = [=](int x, int z) {
    return x + z + first;
};
int(decltype(lambda)::*ptr)(int, int)const = &decltype(lambda)::operator();
std::cout << "test = " << (lambda.*ptr)(2, 3) << std::endl;

If you want to return this function and execute it from somewehere else. (Which is actually possible with lambdas) you have to save the object:

// OT => Object Type
// RT => Return Type
// A ... => Arguments
template<typename OT, typename RT, typename ... A>
struct lambda_expression {
   OT _object;
   RT(OT::*_function)(A...)const;

   lambda_expression(const OT & object)
      : _object(object), _function(&decltype(_object)::operator()) {}

   RT operator() (A ... args) const {
      return (_object.*_function)(args...);
   }
};

auto capture_lambda() {
  int first = 5;
  auto lambda = [=](int x, int z) {
    return x + z + first;
  };
  return lambda_expression<decltype(lambda), int, int, int>(lambda);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Excellent @Noxxer! I've been googling and googling. Nothing clear. This is clear. And it works. Note that in the 1st (of 3) examples, I did have to prepend a decltype(lambda):: to *ptr, but the 2nd and (most importantly) 3rd examples worked as is. I just had to cobble together a 2 liner main for the 3rd, but that was a reasonable drill. Thank you.
Your welcome and thank you for the nice comment. You find "a better implementation" for the third example here at the end of my answer: stackoverflow.com/questions/28746744/…
0

Fct is not a super type of the lambda you're trying to pass. (Roughly because function pointers take up less storage than this kind of lambda) You probably want to use std::function<...> as the type for Fct, and not a typedef'd function pointer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.