Boost logo

Boost :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-07 12:41:21

----- Original Message -----
From: "Howard Hinnant" <hinnant_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Thursday, March 07, 2002 12:02 PM
Subject: Re: [boost] Re: std::complex design (Was: N-Dimensional array

> On Thursday, March 7, 2002, at 10:39 AM, David Abrahams wrote:
> > Just out of curiosity, what do you think the alternative could have
> > been?
> >
> > int f(double); // 1
> > int x = f(double()); // 2
> >
> > In line 2 above, if double() produced an uninitialized value
> > would have produced undefined behavior. Would you have advocated
> > double() produces an undefined-but-copyable value?
> I think that scalar() should call the scalar's default constructor.
> I think a scalar's default constructor should be a no-op. If you copy
> such an object, it's your problem. Maybe your hardware won't mind,
> maybe it will. Such a design would have been more consistent with C,
> and easier to understand.
> There are always ways to initialize an object. But once
> is made mandatory, getting an uninitialized object becomes more
> difficult. Mandatory initialization goes against the "don't pay for
> what you don't use" philosophy of C.

It's not mandatory:

template <class T>
struct uninitialized
    T value;
    operator T const&() const { return value; }

> Referring to Andy's fine paper: There are better techniques available
> today to getting a default value into map than those in the paper,
> if scalar() is a no-op. Such techniques either weren't developed, or
> weren't widely enough known at the time this paper was written.

Oh, sure. I just ignored the map stuff.

> vector<double> v(100);
> Does not have to be "undefined". It could have meant an array of
> uninitialized doubles of length 100. It would have been more like:
> double* v = new double[100];
> And if that's not what you wanted, then you've always got:
> vector<double> v(100, 0.0);

Yep, that would be fine with me.

> To answer your question directly:
> int x = f(double());
> If that's really what you want to do... It could have had the same
> meaning as:
> double temp;
> int x = f(temp);
> If you want to send 0, then it is not that much harder to write:
> int x = f(double(0));
> or simply
> int x = f(0);
> Bottom line: Uninitialized scalars were viewed as a problem that
> solving. With the benefit of 20/20 hindsight, uninitialized scalars
> were a feature, not a bug.

Hmm, I'm unconvinced. If you're trying to write generic code, I don't
think you should have to write this just to call a function with a
default-constructed value:

template <class T, void (*f)(T), bool is_scalar =
struct call_with_default_constructed
    static void execute() { f(T()); }

template <class T, void (*f)(T)>
struct call_with_default_constructed<T,f,true>
    static void execute() { f(T(0)); }

And you'd need a combinatoric suite of these just to make it work for
multiple arguments.


Boost list run by bdawes at, gregod at, cpdaniel at, john at