$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-08-07 09:15:49
On Tuesday 07 August 2001 09:26, you wrote:
> From: "Douglas Gregor" <gregod_at_[hidden]>
>
> > Without the ability for a user to specify the name of the data member
>
> (which
>
> > would require either macro tricks or a core language change), I think
>
> that
>
> > this particular idiom does not lend itself well to being translated
>
> into a
>
> > reusable, generic library.
>
> It certainly would be nice to have a nicely named member.  For some
> small classes it is not important, but in general a meaningful name is
> needed.  Fortunately, a meaningful name can be attached to the member by
> typedefing the base class and using the qualified access to the member.
> The user code would look like:
>
> class foo: base_from_member<bar_type> {
>     typedef base_from_member<bar_type> meaningful_name;
>
>     void fn() {
>         meaningful_name::member.whatever();
>     }
> };
>
> The cost is an extra line of code, but that is still a nice savings over
> an entirely separate class.  Using base_from_member also avoids the
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;
};
As for savings, a rough count says:
        - Using the base_from_member approach requires ~80 characters of typing up 
front (to derive from the class and typedef it), plus another 8 characters 
for each use of the variable.
        - Hand-coding the approach requires ~120 characters of typing (creating the 
base_initializer_bar class and inheriting it).
Obviously the counts vary from instance to instance, but the savings here is 
negated if the member is accessed only five times.
> 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
        - 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?)
        - Might save on typing
> So overall, even though a perfect solution isn't available, I think that
> a base_from_member class would be the best of the alternatives, and
> would be a useful addition to boost.
        Doug