Re: [boost] [optional] generates unnessesary code for trivial types

optional< T& > is a useful thing when you want to apply operators (such as relation operators or streaming) to the referred value. In generic code you don't have to specialize for pointers to do the right thing. I'm going to use this property in my Boost.Log library.
Andrey, would you mind giving us a short example of how you want to use an optional reference? I am in the middle of designing the new optional interface for TR2, and came to the conclusion that in order to avoid counter-intuitive semantics for optional reference assignment, I had better remove it at all; that is, optional references are to be limited: they should provide no assignment. You could still use optional values and optional references in generic code but with reduced interface: template <typename T> // T is a ref or a value void use( std::tr2::optional<T> opt, T nval ) { if (opt) { std::cout << *out; // fine *opt = nval; // fine, assigning T's not optionals opt = nval; // invalid if T is a ref opt = opt; // invalid if T is a ref } if (needToRebindAReference()) { opt.emplace(nval); // valid - always rebinds } }; Would such a limited interface as I described above be enough for your generic usage of optional? Regards, &rzej

On Thu, Feb 9, 2012 at 3:20 PM, Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
Andrey, would you mind giving us a short example of how you want to use an optional reference? I am in the middle of designing the new optional interface for TR2, and came to the conclusion that in order to avoid counter-intuitive semantics for optional reference assignment, I had better remove it at all; that is, optional references are to be limited: they should provide no assignment. You could still use optional values and optional references in generic code but with reduced interface:
template <typename T> // T is a ref or a value void use( std::tr2::optional<T> opt, T nval ) { if (opt) { std::cout << *out; // fine *opt = nval; // fine, assigning T's not optionals opt = nval; // invalid if T is a ref opt = opt; // invalid if T is a ref }
if (needToRebindAReference()) { opt.emplace(nval); // valid - always rebinds } };
Would such a limited interface as I described above be enough for your generic usage of optional?
My code is not yet set in stone, and actually, it doesn't use optional references yet. But it looks like it should be enough for my needs, assuming optional<T&> is still going to support the same relation operators as optional<T> with the same semantics. The general idea is that I build a Boost.Phoenix expression (usually, a predicate or a streaming expression) where some of the terminals may result in optional references (references allow to avoid expensive copying). When the expression is executed, it should operate on the referred values, if present, or execute a fallback logic otherwise. In my context, the required behavior is almost exactly what optional<T&> provides. I have a question though. Why prohibit opt = opt assignment? It looks quite safe and has a fairly obvious behavior. If I have an optional reference as a member of my class, the lack of assignment in optional would force me to define a custom assignment operator for my class. This seems to be an unnecessary requirement. Also, in the source code I dealt with I often saw people writing something like opt = optional<T>() to clear the value. This would break with references for no apparent reason.
participants (2)
-
Andrey Semashev
-
Andrzej Krzemienski