3

I'm not sure, but maybe you can help me.

How can I access to a variable inside a lambda? Example:

float lim;

int main()
{
  std::cin >> lim;
  std::vector<float> v = {1.0f,4.5f,3.9f,0.2f,8.4f};
  v.erase(std::remove_if(v.begin(),v.end(),[](float f){return f > lim}),v.end());
  for (auto i : v) std::cout << i;
  return 0;
}

So this example works, I can specify a value 'lim' and all values in the vector bigger than lim will remove inside the vector. But how can I do this avoiding a global variable lim to hold the value?

Thanks.

0xf10
  • 108
  • 1
  • 11

1 Answers1

3

Use lambda with capture. Notice the [&].
Here is a demo.

#include <iostream>
using namespace std;

int main() {
    int k=0;int n=0;

    auto func1=[=]()mutable{k=1;n=1;};  //capture k by value
    func1();
    std::cout<<k<<std::endl;  //print 0

    auto func2=[&](){k=2;n=1;};         //capture k by reference
    func2();
    std::cout<<k<<std::endl;  //print 2  (k changed)

    auto func3=[k]()mutable{k=3;/* n=1; compile fail*/}; //capture k by value
    func3();
    std::cout<<k<<std::endl;  //print 2

    auto func4=[&k](){k=4;      /* n=1; compile fail*/}; //capture k by reference
    func4();
    std::cout<<k<<std::endl;  //print 4  (k changed)
} 

More about mutable : Why does C++0x's lambda require "mutable" keyword for capture-by-value, by default?

Community
  • 1
  • 1
javaLover
  • 6,347
  • 2
  • 22
  • 67
  • 1
    This is a correct answer. It would be a good answer if it also discussed (briefly) the different ways of capturing (`[&]` vs. `[=]` vs. `[lim]` vs. `[&lim]`). – Angew is no longer proud of SO Apr 06 '17 at 12:36
  • @Angew Thank for let me try, that is also new for me. – javaLover Apr 06 '17 at 12:46
  • @Angew I ponder - it is strange that I need the word "mutable". Is this rule (need "mutable") come at the same time as "lambda"-invention? or is it *invented* in later standard of C++? ..... I always use [&], so I have never known about it. – javaLover Apr 06 '17 at 12:50
  • 1
    @javaLover This application of `mutable` (in lambda expressions) has been there since their conception in C++11. How it works internally is that by default, the closure type's `operator()` is a `const` member function. Using `mutable` makes it non-const. – Angew is no longer proud of SO Apr 06 '17 at 13:07
  • Side note: always using `&` can be dangerous with lambdas which can outlive their immediate scope (e.g. be stored in a `std::function` somewhere). – Angew is no longer proud of SO Apr 06 '17 at 13:07
  • @Angew Thank a lot, so insightful! – javaLover Apr 06 '17 at 13:11
  • 1
    @0xflotus, You capture nothing. You also don't capture anything you don't use if you do `[&]` or `[=]`. And taking something by non-const reference is bad practice when not modifying it. Taking primitives by reference instead of by value is bad practice too. – chris Apr 06 '17 at 22:43
  • 1
    @0xflotus You might just want to review [appropriate documentation](http://en.cppreference.com/w/cpp/language/lambda). – Angew is no longer proud of SO Apr 07 '17 at 06:52