Boost logo

Boost :

From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-09-23 15:51:10


Gennadiy Rozental wrote:
> "John Torjo" <john.lists_at_[hidden]> wrote in message
> news:4152776F.8040303_at_torjo.com...
>
>>>inline formatob_t & format( format_type s)
>>>{
>>> FormatObject::format( s );
>>> return( *this );
>>>}
>>>
>>>formatob( vec ).format( " + " )
>>>
>>>has the same type as
>>>
>>>formatob( vec )
>>>
>>>What are you talking about? Why would you bother what
>
> FormatObject::format
>
>>>is returning?
>>>
>>
>>So that you can manipulate the formatob() object multiple times, like:
>>formatob().do_this().do_that().and_that_too();
>
>
> [I don't know why you removed original code. Let see it again.]
>
> You must be joking. Do you think I can't read code??
> formatob().format() return *** *this **** NOT FormatObject::format();
>
> So my question still stand.

FormatObject is conceptually defined as:

    class FormatObject
    {
       inline FormatObject & format( const DelimiterType & s )
       {
          // ...
          return( *this );
       }
    }

I *know* it is not defined like that (it is defined in formatter_t), but
that is how it *behaves*. This works since formatter_t takes a
ReturnType template parameter that tells formatter_t what to return so
you don't need to forward the functions in FormatObject.

The formatob_t class - to which you refer to - does need to forward the
'format' functions because it is defined as:

    template< class FormatObject >
    class formatob_t: public FormatObject
    {
       inline formatob_t & format( const DelimiterType & s )
       {
          FormatObject::format( s ); // return type == FormatObject
          return( *this );
       }
    };

However... I have just had a brainwave, utilizing a technique like
std::allocator::rebind< T >::type.

    template< typename CharT, class RetType >
    struct wrapper_decorators
    {
       decorator< CharT, 2 > separator;

       template< class RetType2 >
       struct rebind
       {
          typedef wrapper_decorators< CharT, RetType2 > type;
       };

       inline RetType & decorate( const value_type & s )
       {
          separator = s;
          return( *static_cast< RetType * >( this ));
       }
    };

This would allow:

    template< typename CharT, class FormatObject >
    class formatob_t: public FormatObject::rebind< formatob_t< CharT,
FormatObject >::type
    {
    };

But then this does not address the fact that you can't do:

    template< typename CharT, class RetType = wrapper_decorators< CharT,
RetType > >
    struct wrapper_decorators;

since wrapper_decorators is an incompletly defined type at the point
when the default for RetType is defined in the template arguments.

This issue can be solved using the current work around. The question is
whether:

    public FormatObject::rebind< formatob_t< CharT, FormatObject >::type

will work as expected. It should set the return type for 'decorate' to
formatob_t; it should also allow calls to 'read' and 'write' to properly
delegate to FormatObject. I have not yet tested whether this works. I
should know in a few days.

Regards,
Reece


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk