Back to lambda library pages
Currently, to include all the headers of the lambda library, you do:
#include <boost/lambda/lambda.hpp>
I suggest that it would be more sensible to have:
#include <boost/lambda.hpp>
- People/Chuck Messenger
The following compiles:
(cout << _1 << "\n")(x);
but this doesn't:
(cout << _1 << endl)(x);
Note that an io manipulator is actually a unary function, taking an ostream as input, and returning an ostream. What complicates things is that it is a template function. Here's the gcc3.2.2 version:
template<typename _CharT, typename _Traits> basic_ostream<_CharT, _Traits>& endl(basic_ostream<_CharT, _Traits>& __os) { return flush(__os.put(__os.widen('\n'))); }
Because it is a template, "endl" has no meaning outside of a context which supplies it type information. If you compile the above, you'll get an error something like "unknown type", since the type of endl can't be deduced.
Normally, in a chain like "cout << 1 << 2", etc, the type of each result of operator<<(), going left-to-right, is the type of the left-most target -- cout in this case. This supplies the necessary type context for endl.
But in the case of "cout << _1 << _2", the type is the lambda functor "constant" type, with the ostream type embedded within it.
In short, it would be nice if the lambda library supported manipulators, but I can't figure out how to do it...
- People/Chuck Messenger
I also faced with the problem and found a partial solution:
// hairy typedef typedef basic_ostream<char, char_traits<char> > & (*omanip) (basic_ostream<char, char_traits<char> >&);
omanip endl_ = &std::endl<char, char_traits<char> >; // Manual specified template params (cout << _1 << endl_)(x); // OK
omanip endl_ = static_cast<omanip>(&std::endl); // Using static_cast one can type less (cout << _1 << endl_)(x); // OK
// The same as above but in one line (cout << _1 << static_cast<omanip>(&std::endl))(x); // OK
All this stuff can be wrapped as follows:
// Ostream manipulator metafunction template<class charT, class traits> struct omanip_t { typedef std::basic_ostream<charT, traits> ostream_type; typedef ostream_type & (*type)(ostream_type &); };
// Ostream-specific manipulator cast template<class charT, class traits> typename omanip_t<charT, traits>::type omanip(std::basic_ostream<charT, traits> &, typename omanip_t<charT, traits>::type manip) { return manip; }
(cout << _1 << omanip(cout, endl))(x); // OK
I think more general facility for transferring template parameters (GoF? "prototype" design pattern for templates) can be written. It could be part of Boost.MPL .
- Vladimir Volodko