[Home]Cookbook - Lambda Library

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

This page is a place where people can find and contribute useful short snippets of code for getting things done with the Boost Lambda Library.

The first few examples are just a copy of the [introductory examples] from the Boost Lambda Library documentation (http://www.boost.org/doc/html/lambda/using_library.html)

Another source of examples is the set of regression tests that are included in the Boost distribution. These are located at {boost_dir}/libs/lambda/test .

Back to lambda library pages


Preliminaries


To get most of these examples to compile, you will need some combination of the following include statements and using declarations.
  #include <boost/lambda/lambda.hpp>
  #include <boost/lambda/bind.hpp>
  #include <vector>
  #include <algorithm>

  using namespace std;
  using namespace boost::lambda;

Examples from the documentation


Initialize the elements of a container, say, a list, to the value 1:

  list<int> v(10);
  for_each(v.begin(), v.end(), _1 = 1);

The expression _1 = 1 creates a lambda functor which assigns the value 1 to every element in v.


Create a container of pointers and make them point to the elements in the first container v:

  vector<int*> vp(10); 
  transform(v.begin(), v.end(), vp.begin(), &_1);

The expression &_1 creates a function object for getting the address of each element in v. The addresses get assigned to the corresponding elements in vp.


Change the values in v. For each element, the function foo is called. The original value of the element is passed as an argument to foo. The result of foo is assigned back to the element:

  int foo(int);
  for_each(v.begin(), v.end(), _1 = bind(foo, _1));


Sort the elements of vp:

  sort(vp.begin(), vp.end(), *_1 > *_2);

In this call to sort, we are sorting the elements by their contents in descending order.


Output the sorted content of vp separated by line breaks:

  for_each(vp.begin(), vp.end(), cout << *_1 << '\n');


Output the sorted content of vp separated by line breaks (prefixed line breaks):

  for_each(vp.begin(), vp.end(), cout << constant('\n') << *_1);


Original examples (not from the documentation)


Get the sum of all the elements in a container:

  vector<double> v;
  ...
  double sum = 0;
  for_each(v.begin(), v.end(), var(sum) += _1)

Call a standard math library function (e.g. floor()) on all the elements of a container:

  vector<double> v;
  ...
  double (*pFloor)(double) = &floor;
  for_each(v.begin(), v.end(), _1 = bind(pFloor,_1) );

Trying to do bind(floor,_1) directly doesn't work. You can also cast floor() within the bind call directly:

  for_each(v.begin(), v.end(), _1 = bind((double(*)(double))floor,_1) );

Call a member function on each element of a container
   struct Thing {
     void dump() { cout << num << "\n"; }
     int num;
   };
   vector<Thing> tv;
   vector<Thing*> tpv;
   ...
   for_each(tv.begin(), tv.end(), bind(&Thing::dump, _1));
   for_each(tpv.begin(), tpv.end(), bind(&Thing::dump, *_1));

Set the value of a member of each element of a container (continued from above)
   for_each(tv.begin(), tv.end(), bind(&Thing::num, _1) = 42);
   for_each(tpv.begin(), tpv.end(), bind(&Thing::num, *_1) = 42);

Calling virtual functions:
struct Base { virtual string speak()=0; };
struct Derived : public Base { virtual string speak() { return "ook"; } };
vector<Base*> v;
ostringstream oss;
//for_each(v.begin(),v.end(),oss << bind(&Base::speak,*_1) << "\n"); // gives error: cannot instantiate abstract class Base
for_each(v.begin(),v.end(),oss << bind(&Base::speak,_1) << "\n"); // compiles and works correctly - WHY?

Thanks, Tim


WANTED

If you're looking for it, and it's not here, put a stub for it below with perhaps a broken bit of lambda code that you thought should work but doesn't.

If you fix one of these broken examples, please move it out of the "WANTED" section of this page.


Fill container with newly constructed containers
// additional includes
#include <algorithm> // fill
#include <boost/lambda/construct.hpp>

typedef vector<int> Row;
typedef vector<Row> Matrix;

Matrix m(5);
// the following line does not work
fill(m.begin(), m.end(), bind(constructor<Row>(), 5));

// // this is the desired result
// for (Matrix::iterator i = m.begin(); i != m.end(); ++i) {
//     *i = Row(5);
// }

// Should perhaps do the following:
// fill(m.begin(), m.end(), _1 = bind(constructor<Row>(), 5));
// This will presumably construct empty Rows, then assign a Row
// of length five for each empty row and assign it to the empty
// row via the assignment operator. Very inefficient. Would appreciate 
// authoritative clarification and/or better option. (From Elliott)

BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited September 23, 2008 6:52 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers