Boost logo

Boost :

From: Ed Brey (edbrey_at_[hidden])
Date: 2001-08-07 09:42:57


From: "Douglas Gregor" <gregod_at_[hidden]>

> > problem of the obfuscation that the hand-coded extra class causes:
it
> > appears that there is a an is-implemented-in-terms-of relation,
which
> > isn't really the intent. Base_from_member makes the intent clear,
which
> > is just to work around an initialization ordering limitation.
>
> If a generic class can be named to make the intent clear, so can a
hand-coded
> one. The hand-coded version also has several advantages:
> - The fact that the idiom is used at all is confined to the base class
list
> and the constructors

Good point. The naming advantage is small. There is still utility in
having a standard name, so a reader unfamiliar with the pattern can
cross-reference the name and look up pre-written documentation on what
is being accomplished. There is no easy way to accomplish this with a
hand-coded class. I consider this a small advantage only. And on the
other hand, since this situation is somewhat rare, an advanced reader
may not be familiar with the boost class, and looking it up may take
longer than figuring out the hand-written code.

> - You can add the exact constructors (for base_from_member) that you
> require. The generic base_from_member cannot catch all possibilities
(should
> each parameter be a ref/const ref/value?)

If the template type deduction is ever different from what you want, you
can always specify the template parameters yourself. Yes, more typing,
but no worse than putting the same in the constructor of the
hand-written version.

> I'm not seeing that it is a savings at all. If at each use we need
towrite
> "meaningful_name::member" instead of "meaningful_name", how long
before we
> have actually no savings? The above example could be hand-coded very
easily:
>
> struct base_initializer_bar {
> base_initializer_bar(const bar_type& b) : bar(b) {}
>
> bar_type bar;
> };

Indeed, hand-coding as such is pretty small, but is the above snippet
always adequet? In some circles, the following would be preferred:

namespace detail
{
  class base_initializer_bar
  {
   protected:
    explicit base_initializer_bar(bar_type const& b): bar(b) {}

    bar_type bar;
  };
} // namespace detail

So it's not quite so small. Even so, if the member is referenced
commonly, it may well still be worth hand coding, since doing so avoids
the need for specifying "::member". On the other hand, if the member is
referenced rarely, then base_from_member would be a convenient shortcut.


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