|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-03-08 07:29:02
----- Original Message -----
From: "rwgk" <rwgk_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, March 08, 2002 12:37 AM
Subject: [boost] Re: container design (Was: std::complex design (Was:
N-Dimensional array))
> --- In boost_at_y..., "David Abrahams" <david.abrahams_at_r...> wrote:
> Howard:
> > I think this is the wrong question. I can imagine a class with a
> > non-trivial construction process but a trivial destruction process.
> For
> > example a class that must keep a pointer to some part of itself to
> > satisfy a class invariant. The pointer must be set in a
> constructor.
> > But the destructor is a no-op. Such a class should not be used with
> > uninitialized_flag. That makes
> > BOOST_STATIC_ASSERT(boost::has_trivial_destructor<T>::value);
> > nothing but false security.
>
> David:
> > All kinds of things: you could assign to an uninitialized T or call
> one
> > of its member functions. Will this cause trouble? Only the author
> of T
> > knows for sure. Furthermore, T's very reason for being might be to
> take
> > action in its constructor. If that's the case, skipping the
> constructor
> > *in and of itself* might be trouble.
>
> Hm.
> Seems that we cannot ignore the assignment operator.
> Here is my revised proposal:
>
> Ideas:
> - Clear cut cases should "just work".
> - The user should have the ability to register custom types
> for uninitialized instantiation of containers.
> - I do not view "no checks at all" as an alternative.
> - Checking for a no-op constructor wouldn't even work for
> std::complex.
>
> Suggested implementation:
>
> Part 1: covers clear cut cases:
>
> template <typename T>
> struct uninitialized_traits<T> {
> { BOOST_STATIC_CONSTANT(bool, value =
> boost::has_trivial_destructor<T>::value
> && boost::has_trivial_assign<T>::value);
> ); };
Why is assignment any "more special" than other member functions?
One plausible answer might be "because it's part of the requirements for
container elements"
> Part 2: user registers a custom type:
>
> template <> struct uninitialized_traits<custom_type>
> { BOOST_STATIC_CONSTANT(bool, value = true); };
>
> Then:
>
> vector(size_t n, uninitialized_flag)
> {
> // allocator is called here
> BOOST_STATIC_ASSERT(boost::uninitialized_traits<T>::value);
> size_ = n;
> }
I still believe the assert is the wrong approach because it interferes
with generic code. Since default construction can always be substituted
for uninitialized construction, why don't you just do that instead where
neccessary?
-Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk