On Sat, Feb 11, 2012 at 2:23 AM, John M. Dlugosz <mpbecey7gu@snkmail.com> wrote:

On 2/10/2012 7:35 AM, Nat Linden wrote:
On Thu, Feb 9, 2012 at 11:05 PM, John M. Dlugosz<mpbecey7gu@snkmail.com>  wrote:

On 2/9/2012 1:49 PM, Nat Linden wrote:

template<typename FUNCTOR>
void ourmacro_f(const FUNCTOR&  f)
{
    f(hidden_ostream_object);
}

#define OURMACRO(EXPRESSION) (ourmacro_f(boost::lambda::_1<<
EXPRESSION))

How is that different from just using:

       #define OURMACRO(EXPRESSION) hidden_stream_object<<  EXPRESSION

Simply that hidden_stream_object really isn't visible in the calling
context. It's local to the context of ourmacro_f().

Sorry, I'm still not seeing the point.  The name hidden_stream_object is not in scope here but ourmacro_f is instead?  So what?

Or, a plain function to return the stream object?

       ostream& get_stream() { return hidden_stream_object; }

       #define OURMACRO(EXPRESSION) get_stream()<< EXPRESSION

Okay, so I've oversimplified the example code. The point is that the boost::lambda::_1 placeholder defers the evaluation, giving you extra control over the operation. Put differently, the expression is evaluated in the context of your function rather than in the calling context. Consider:

template<typename FUNCTOR>
void ourmacro_f(const FUNCTOR&  f)
{
    if (some_condition)
    {
        f(hidden_ostream_object);
    }
}

or how about:

template<typename FUNCTOR>
void ourmacro_f(const char* expr_string, const FUNCTOR&  f)
{
    try
    {
        f(hidden_ostream_object);
    }
    catch (const std::exception& e)
    {
        hidden_ostream_object << "Exception " << typeid(e).name() << " evaluating (" << expr_string << "): " << e.what() << std::endl;
    }
}

#define OURMACRO(EXPRESSION) (ourmacro_f(#EXPRESSION, boost::lambda::_1 << EXPRESSION))