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
library

> 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
f(double())
> > would have produced undefined behavior. Would you have advocated
that
> > double() produces an undefined-but-copyable value?
>
> I think that scalar() should call the scalar's default constructor.
And
> 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
initialization
> 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,
even
> 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
needed
> 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 =
boost::is_scalar<T>::value>
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.

-Dave


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