Boost logo

Boost :

From: Aleksey Gurtovoy (alexy_at_[hidden])
Date: 2001-08-09 23:39:16


Douglas Gregor wrote:
> I have no comments on the code itself that haven't already
> been covered, except to revisit the naming of the "ron_"
> member variable. This led me to the question "what is a
> good name for this variable?" Any choice has to be generic
> enough to name any possible member variable, but because
> of this genericity it is impossible for the name to
> communicate any meaning to the user. So how does one
> write readable code using this idiom?
> Accessor/mutator methods can be used for clarity, but this
> desugaring seems to overshadow the benefits of using the
> library vs. manually coding the idiom.

IMO it's not. The purpose of the technique is to make it possible to pass a
reference (pointer) to a (fully constructed) class member to a base class
constructor, and often the base class is the only one that actually does use
that member; the derived class just provides storage, "hosts" the member,
because it knows it's concrete type, but it never actually refer to it
except the base class initializer in the member initialization list. To be
specific ;), here is a (simplified) real life example that demonstrates
exactly that kind of usage of the idiom:

// ixml_stream.h
struct ixml_stream
{
    ixml_stream(std::istream&);
    //...
};

// ixml_stringstream.h

#include "ixml_stream.h"
#include "boost/utility/base_from_member.hpp"

struct ixml_stringstream
    : private boost::base_from_member<std::istringstream>
    , public ixml_stream
{
    ixml_istringstream(std::string const& input)
      : boost::base_from_member<std::istringstream>(input)
      , ixml_stream(member) // the only use of 'member' name
    {
    }
    //...
};

So a generic name of the member is not a problem here at all; that's more
important, in my experience this is the most common kind of situation when
you need to apply the idiom (base class(es) do the work, and derived class
just hosts the required objects and passes them to the base class
constructor(s)). IMO using a helper class here is much more preferable than
repeatedly writing small classes that clutter headers, create a possibility
of name clashes, and IMO take too much space for implementation details:

// ixml_stringstream.h

#include "ixml_stream.h"
// #include "boost/utility/base_from_member.hpp"

namespace detail {
struct base_from_istringstream
{
 protected:
    base_from_istringstream(std::string const& input)
        : m_input_stream(input)
    {
    }
 
    std::istringstream m_input_stream;
};
} // namespace detail

struct ixml_stringstream
    : private base_from_istringstream
    , public ixml_stream
{
    ixml_istringstream(std::string const& input)
      : base_from_istringstream(input)
      , ixml_stream(m_input_stream)
    {
    }
    //...
};

Personally, I think it's too much to pay for having the

      , ixml_stream(member)

line being written as

      , ixml_stream(m_input_stream)
 

> Using the library saves a small amount of typing up front
> (the creation of a class containing a single member), but it
> requires more typing overall to preserve the readability of
> code using this member.

Hypothetically - may be, but I don't think that this is how the things are
in the real world. Our experience here at work shows that typical contexts
of application of the idiom are very like the above example, that IMO
clearly benefits from using generic "base_from_member" class template
instead of hand-crafted one.

[...]
> Overall, my view is that this library should not be accepted
> into Boost.

I think it should be accepted, pending the suggestions brought up by Ed Brey
in his first message on the topic
(http://groups.yahoo.com/group/boost/message/15406).

Aleksey


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