Boost logo

Boost :

From: rwgk (rwgk_at_[hidden])
Date: 2002-03-08 00:37:01


--- 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);
); };

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;
      }

Ralf


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