Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2004-06-03 15:03:39


From: "Reece Dunn" <msclrhd_at_[hidden]>
> Rob Stewart wrote:
> >
> >Couldn't substr() be a pure virtual function in char_string that
> >deferred to the derived class to create a copy of itself? The
> >derived class can just create a duplicate of itself, including
> >the current capacity. That capacity is guarranteed to be
> >sufficient to hold any substring requested.
>
> The return type cannot be boost::fixed_string_base because of the whole ABC
> issue. Therefore, the return type needs to be a reference or a pointer. It
> is possible to do this, and have:
>
> class fixed_string
> {
> inline fixed_string_base & substr_( size_type pos, size_type n )
> {
> return( this_type( *this, pos, n ));
> }
> };

I didn't mean for it to be returned by value (because it would
slice) and I certainly didn't mean to for it to return a pointer
or reference to a temporary.

> This is problematic because of returning the address of a temporary - and
> leads to unpredictable output.

It's more than problematic. It results in undefined behavior.

> I am looking for a better solution to this. I am also thinking about how to
> remove the ABC from the implementation using a technique pointed out by
> someone on this thread (can't remember who):
>
> class fs_base
> {
> size_t len;
> szie_t capacity; // needed for buffer-safe operations
> CharT str[ 1 ];
> // string manipulation functions
>
> fs_base( size_t c ): capacity( c ){}
> };
>
> template< size_t n >
> class fixed_string: public fs_base
> {
> CharT data[ n ];
> fixed_string(): fs_base( n ){}
> };
>
> I'll need to look into this, to see what effect this will have, to see if it
> is a possible replacement for the ABC. What do other people think?

This has the definite benefit of putting all of the meat in the
base class, leaving to the derived class only the initialization
of the string, thus avoiding most virtual functions. In order
for fs_base::substr() to do its job, however, it would still need
the derived class to create an instance from the designated
substring; the base class doesn't know, at compile time, the
required capacity. That implies a pure virtual function, sort of
a clone(), that the derived class must implement.

The only inherent danger in this approach is that the author of
the derived type must be trusted to allocate the necessary number
of bytes. It is convenient that the base class allocates one
byte as that can be the reserved byte for the null terminator;
the derived class only has to allocate N bytes.*

* Change "bytes" to "characters" to allow for wchar_t.

-- 
Rob Stewart                           stewart_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

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