
2013/1/13 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>:
Le 13/01/13 09:58, Antony Polukhin a écrit :
2013/1/6 Joel de Guzman <djowel@gmail.com>:
Hi,
I just looked at the current state of variant and noticed that the implementation of recursive_variant's move ctor seems to be not as optimal as I hoped. The current implementation as written is:
...
I`ve finally got back from vacation, so let me add my 2 kopecks.
We can make move constructor fast and noexcept (just like Joel proposed) and also guarantee non-empty behavior. The idea is to delay construction of object:
T& get() { if (!get_pointer()) p_ = new T; return *get_pointer(); }
const T& get() const { if (!get_pointer()) p_ = new T; // mark p_ as mutable return *get_pointer(); }
So if move occurred object is empty, and if it is required again - it is default constructed.
Any objections?
This would make less efficient the get operation. I would prefer to force the boost::blank default construction.
I see no big difference between "BOOST_ASSERT(p_);" and "if (p_) p_ = new T;" except default construction requirement for T. Construction and "new" call will occur only if recursive_wrapper is being reused after move, which must be a really rare case. boost::blank is relevant to boost:variant, not to recursive_wrapper: boost::variant<boost::blank, boost::recursive_wrapper<foo> > var(std::move(variable)); // Will call recursive_wrapper(recursive_wrapper&&) if `variable` is a recursive_wrapper type or boost::blank(boost::blank&&) if `variable` is a boost::blank -- Best regards, Antony Polukhin