Pages

The use of ret in a boost lambda expression

Another nuisance in the usage of the boost lambda expression is that the compiler could be get confused in the translating of the expression and can't get the correct return type from a token. The more annoying fact in this is that we get an error message that is incredibly long and quite difficult to understand. But at least we should find out that the problem comes from a 'sig' symbol and from deducing argument types.

The problem could look obscure, at least the first time, but the solution is easy: just explicitly tell the compiler the return type it should expect using the ret<>() function, or its shortcut bind<>().

The good news is that this problem is no more, when using the C++0x implementation.

Let's see an example:

#include <iostream>

#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"

using namespace boost::lambda;

using std::cout;
using std::endl;

class Doubler
{
public:
int operator()(int i) const { return i*2; }
};

void lambda03()
{
Doubler d;

// this doesn't work:
//(cout << _1 << " * 2 = " << (bind(d, _1)) << '\n')(12);

(cout << _1 << " * 2 = " << (ret<int>(bind(d, _1))) << '\n')(12);
(cout << _1 << " * 2 = " << (bind<int>(d, _1)) << '\n')(12);

[d] (int j) { cout << j << " * 2 = " << d(j) << endl; } (12);
}

The commented boost lambda expression just does not compile. We should help the compiler to figure out the type returned by the token involving the binding to the Doubler functor, using what it is showed in the next line, by the ret<>() function or, more concisely, we could use the bind<>() function, that combines binding to the return value identification.

And, when we can, using the C++0x implementation could save us a lot of head scratching.

More information on boost lambda and ret<> in "Beyond the C++ Standard Library: An Introduction to Boost", by Björn Karlsson, an Addison Wesley Professional book.

No comments:

Post a Comment