Boost logo

Boost :

Subject: Re: [boost] [optional] std::tr2::optional
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2011-11-18 18:16:43


> > * Conversion explicit conversion to bool should be declared as
explicit.
>
> Doesn't an explicit conversion disallows to use it in a conditional
> expression as in
> if(opt) {}

I believe that the primary motivation for the explicit conversion operators
was to provide a simpler alternative for safe-bool idiom, and address cases
like this one.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf

> > * Should exception safety guarantees for assignment operations be
enforced?
> > In boost::optional they only provide a basic guarantee.
> > One option is to provide strong guarantee for types T which implement
> > operator= with strong guarantee, and give basic guarantee for other
cases
> > Other option (not sure if it is possible) is to provide strong
guarantee
> > for all cases at the cost of run-time performance (heap allocation).

> Provide the same exception guaranties as the T assignment seems the more
> reasonable.

My apologies, I wrote this in a hurry an didn't make myself clear. There
are three cases to consider (leaving move assignment and no-throw copyable
types aside):
1. Our stored type T provides a strong assignment - the choice is obvious:
optional<T>'s assignment is also strong
2. T has "basic" assignment - the natural choice is to provide also a basic
guarantee for optional<T>'s assignment.
3. T is neither copyable nor moveable -- it is like a scope guard, or
boost::scoped_ptr. In this case optional<T> still provides assignment by
making a "pseudo destructor call" followed by a call to placement new. --
but this gives only basic guarantee.
The question is if for this third variant we should be happy with only
basic guarantee or to use a trick boost::variant is using with auxiliary
heap-allocated object? (I do not even know if this is applicable though).

> > template< typename ... Args>
> > optional( Args&& ...args );
> I like them.
> > The constructor will clash with another optional constructor:
> > optional<T>::optional( bool cond, const T& val );
>
> I don't understand why.

Currently boost::optional provides this constructor:
optional<T>::optional( bool cond, const T& val );
If cond is true the optional is initialized with object val, otherwise it
is uninitialized.

Now suppose I have a following type:

  struct MyType {
    bool on;
    int m1;
    int m2;
    MyType( bool on, MyType const& rhs )
      :on{on}, m1{rhs.m1}, m2{rhs.m2} {}
  };

MyType mt { true, 1, 2 };
boost::optional<MyType> o1{ true, mt }; // optional initialized with mt
(copy ctor used)
boost::optional<MyType> o2{ boost::in_place(true, mt) }; // uses 2-arg ctor

But if std::tr2::optional has "variadic" constructor:
std::tr2::optional<MyType> mt{ true, mt }; // uses 2-arg ctor

Regards,
&rzej


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