|
Boost : |
From: Reid Sweatman (reids_at_[hidden])
Date: 1999-08-23 13:35:42
I agree with most of your remarks. The solution I like best is the
two-constructor version. Here's why. First, I'd argue that the semantics
of the two-argument form are exactly what I expected them to be; in other
words, if the boolean is false, then no construction gets done, no matter
what. As for your case (4), I think we can take it for granted that none of
us would write something like that <g>. It might be better to swap the
order of the arguments, though. However, this solution still suffers from
the same problem as the last one Csaba offers, which is that it prevents you
from using initialization lists, which avoid the extra object copy. In a
large container, the saved time could add up. Although, being stuck with
VC++ v5 SR3 for the time being, I avoid initialization lists because that
implementation has at least two very severe bugs. Shame. If anyone has any
idea of how to light a fire under MS's System Languages people, please let
me know. (And that's as far off-topic as I'll stray...please note that it
was a question, not a flame).
> -----Original Message-----
> From: Csaba Szepesvari [mailto:szepes_at_[hidden]]
> Sent: Saturday, August 21, 1999 8:10 AM
> To: boost_at_[hidden]
> Subject: [boost] Re: boost digest (was initialization)
>
>
> James Curran/MVP wrote:
>
> > From: Reid Sweatman <reids_at_[hidden]>
> >
> > >class foo
> > >{
> > >public:
> > > foo(value_type& T = nValue,bool initialise = false)
> > >{ if(initialize) Initialize(T); }
> > >};
> >
> > Am I missing something? I don't see that working as expected...
> > Consider the simplified:
> >
> > class foo
> > {
> > int n;
> > public:
> > foo(int N = 5,bool initialise = false)
> > { if(initialize) n = N; }
> > };
> >
> > Now, Case #1
> > Written: Foo X;
> > Effective: foo X(5,false);
> > Effect: X.n is not initialized.
> >
> > Case #2
> > Written: foo X(7)
> > Effective: foo X(7, false);
> > Effect: X.n is not initialized.
> >
> > Case #3
> > Written: foo X(7, true);
> > Effective: same
> > Effect: X.n is initialized to 7.
> >
> > Case #4
> > Written: foo X(, true);
> > Effective: foo X(5, true); // almost....
> > Effect: X.n would be initialized to 5, if it weren't a syntax error.
> >
> > So, it would seem, that the only place where the
> default for the
> > second-to-last parameter could be used it, is an error.
> Furthermore, the
> > effect of case #2 is counter-intuitive.
>
> You could change the initialization argument to a template
> argument as I
> proposed before and then things would work as one would
> expect them to work.
> However, I have to agree with Reid (see his earlier mail)
> that having just
> two constructors, one without any parameters (and doing no
> initialization)
> and one with a parameter used in the initialization would do
> the job. If you
> have an idea of how to initialize your class you could add a third
> constructor that would do the initialization with the default
> value. This
> third constructor would have an enum parameter (just to
> differentiate this
> constructor from the others):
> class foo
> {
> public:
> ...
> typedef enum { init_with_default } Init_with_default;
> foo( Init_with_default ) { Initialize(); }
> };
> and
> foo f(init_with_default);
> would then do the job.
>
> But the main reason of writing this letter is to let me make
> the observation
> that normally you initialize vectors by passing a constructed
> object to the
> vector constructor:
>
> std::vector<foo> foovector( 10, foo(5) );
>
> - this means copy construction which may be as efficient as direct
> initialization (but this depends on many factors including the actual
> implementation of the default allocator of the vector). So
> for vectors things
> are nice and simple.
>
> What you cannot do in this way is to have an initialized
> array of foos:
>
> foo* fooarray = new foo[5];
>
> - for this you would need a default constructor that is doing the
> initialization (i.e. an initialization constructor is not
> sufficient here).
> I don't see any way to have a class from which I could create both
> initialized and unitialized arrays: there is only one default
> constructor and
> it can only do one thing (either initize or don't initialize).
> You could make the whole class a template with a bool
> parameter denoting if
> initialization is needed - this seems to be the only way to
> overcome this
> problem, e.g.
> template <bool init =
> true_if_you_like_default_initialization_otherwise_false>
> class foo
> {
> public:
> foo() { if (init) Initialize(); }
> };
> then you could have all versions:
> foo<>* fooarray1 = new foo<>[5];
> foo<true>* fooarray1 = new foo<true>[5];
> foo<false>* fooarray1 = new foo<false>[5];
>
> but probably this has an unacceptably high price: the initialized and
> unitialized versions of foo are actually different classes!
> You would need
> quite an amount of work to make them equivalent.
> Now comes the idea that having two classes allows one two
> have to default
> constructors and a clever derivation may actually solve the problem:
> class foo
> {
> public:
> foo() { };
> ..
> };
> class foo_init : public foo
> {
> public:
> foo_init() { Initalize(); }
> ..
> };
> (obviously, the other way around, having foo_init as the base
> class won't
> work for obvious reasons).
> Then you are allowed to write:
>
> foo* fnarray = new foo[5];
> foo* fnarray2 = new foo_init[5];
>
> - perhaps a bit strange piece of code, but works. The price
> is minimal (for
> simple classes).
> But anyway, I think that all these are two complicated and
> using vectors is a
> better way to solve the "initialize or not to initialize dilemma".
>
> - Csaba
>
>
>
> --------------------------------------------------------------
> ----------
> MyPoints-Free Rewards When You're Online.
> Start with up to 150 Points for joining!
> http://clickhere.egroups.com/click/805
>
>
> eGroups.com home: http://www.egroups.com/group/boost
> http://www.egroups.com - Simplifying group communications
>
>
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk