|
Boost : |
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk