Expressions are essentially functors, with an ability to compose itself with other expressions. You start with a simple expression, and then you go on composing more complex expressions using simpler ones. It can be best understood by examples. So here you go.

//a function which takes a functor as argument
//and then invoke it passing 0 to 9, and print the result.
template<typename Functor>
void f(Functor && fun)
{
  for ( int i = 0 ; i < 10 ; i++ ) 
     std::cout << fun(i) << std::endl; //invoke fun for each i in [0, 10)
}

expression<int> x;  //x is a simple expression (identity expression)

f(x); //print 0 to 9

auto y = x * x - 4 * x + 4; //compose an expression y using x and literals

f(y); //print value of (i * i - 4 * i + 4) for each i in [0, 10)

f( (x + 10)* y ); //x and y are expressions. compose further using them 
                  //and pass the resulting expression to f which
                  //prints value of [(i + 10) * (i * i - 4 * i + 4)] for each i in [0, 10)

Comparison of expression with lambda

Since expressions are functors, they can be used in place of lambdas, because they simplify the code. Consider this code which uses lambda,

std::vector<int> v {0,1,2,3,4,5};

auto it = std::find_if(begin(v), end(v), [](int i) { return i == 2; } );

Using expresson the above std::find_if can be written as,

expression<int> x; //declare an expression variable first

auto it = std::find_if(begin(v), end(v),  x == 2 );

which is much more concise. Well that is not where you would use expression (or lambda for that matter), because you would use std::find as:

auto it = std::find(begin(v), end(v), 2 ); //simplest!

That is better expressed without expression! But consider this code which uses expression:

auto it = std::find_if(begin(v), end(v), (x*x+4) == (4*x) ); //find x such that LHS == RHS

Now compare it with the lambda version,

auto it = std::find_if(begin(v), end(v), [](int i ) { return (i*i+4) == (4*i); } ); 

The advantage of expression over lambda is that once you declare x, you can reuse it and that too in many different ways. Few more examples,

if ( std::any_of(begin(v), end(v), x < 0 ) )
{
    std::cout << "v contains at least one negative number." << std::endl;
}

int n = std::count_if ( begin(v), end(v), x % 2 == 0 ); //count even numbers
std::cout  << "v contains " << n < " even numbers." << std::endl;

As we see, expressions make the code concise without destroying its readability. On the contrary, it increases the readability.

Member expression

C++11 has std::mem_fn which creates wrappers for member-function-pointers and member-data-pointers. The following example illustrates its usage:

struct person
{
    int age;
    std::string name;
    int get_age() const { return age; }
};

std::vector<person> ps = get_persons();

auto age = std::mem_fn(&person::age); //creates a wrapper for person::age 
std::vector<int> ages;

std::transform(ps.begin(), 
               ps.end(), 
               std::back_inserter(ages), 
               age); //for each element e in ps, get `e.age` and add it to vector `ages`.

for(auto && x : ages)
    std::cout << x << std::endl; //print each element of ages
	

The problem is that the wrapper age, created by std::mem_fn, doesn’t support composition. We cannot use it to do this, for example:

//pseudocode : it would not compile
std::transform(ps.begin(), 
               ps.end(), 
               std::back_inserter(ages), 
               10 * age );  //add 10 times of age to the vector `ages`.

To accomplish this, composition library provides a function called memexp which is just like std::mem_fn, except that it supports composition. So with it we can do this:

auto age = memexp(&person::age); //creates a composable wrapper!
std::transform(ps.begin(), 
               ps.end(), 
               std::back_inserter(ages), 
               10 * age ); //okay now

Or we may use member function of person instead, as:

auto age = memexp(&person::get_age); //notice the difference here!
std::transform(ps.begin(), 
               ps.end(), 
               std::back_inserter(ages), 
               10 * age ); //same as before!

We can use it in filtering as:

std::vector<person> filtered;
std::copy_if(ps.begin(), 
             ps.end(), 
             std::back_inserter(filtered), 
             age >= 13 && age <= 19 ); //filter teenagers

which is equivalent to this lambda version:

std::vector<person> filtered;
std::copy_if(ps.begin(), 
             ps.end(), 
             std::back_inserter(filtered), 
             [](person const & p) { return p.age >= 13 && p.age <= 19 } );

Apart from being concise, the expression version is definitely more readable. Even more, memexp allows us to pipe as shown below (using _m which is a wrapper object of memexp):

//first get the name of person object,
//which then gets passed to the next pipe 
//which returns the size of the name.
auto namesize = _m(&person::name) | _m(&std::string::size); //we can also use memexp instead.

std::vector<std::size_t> sizes;
std::transform(ps.begin(), 
               ps.end(), 
               std::back_inserter(sizes), 
               namesize); //note: namesize is composable, so we can pass (namesize * 10) instead!

which is same as (lambda version):

std::vector<std::size_t> sizes;
std::transform(ps.begin(), 
               ps.end(), 
               std::back_inserter(sizes), 
               [](person const & p) { return p.name.size(); } );