[Home]Suggestions - Lambda Library

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

This page is for making suggestions for improvements to the Boost Lambda Library.

Back to lambda library pages


boost/lambda.hpp

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


Handle io manipulators

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



BOOST WIKI | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited January 16, 2006 8:13 am (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers