
on Thu Apr 30 2009, Ion GaztaƱaga <igaztanaga-AT-gmail.com> wrote:
David Abrahams wrote:
are you familiar with http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2855.html ?
I've just skimmed part of the discussion, just to see what the problem was and to think that noexcept is a great idea that can also help performance and code size.
Until the committee decides exactly how to handle it and compilers catch up with the feature they add, we need a workaround for that problem, both for C++03 and C++0x. The simplest approach requires a trait called has_nothrow_move<T> which can be used to SFINAE-out pair's move constructor unless its members all have a nonthrowing move constructor. It would be reasonable to say
template <class T> struct has_nothrow_move : has_move_constructor {};
What does has_nothrow_move exactly mean? It means that type has a nothrow T(T &&x) overload or that conversion from rvalue ref to a type does not throw (including copy constructor if the type has not overloaded the constructor with both const & and &&)?
It means that construction from an rvalue of the same type doesn't throw.
In the working draft there are some "move" traits that are confusing to me regarding this issue (MoveConstructible requires RvalueOf<T> && Constructible<T, RvalueOf<T>::type> which I think is true for C++03 types).
Yes, anything that is CopyConstructible is MoveConstructible. It's not great terminology, but you have to think of the T(move(x)) (where x is of type T) as "the move operation" regardless of whether it actually moves or copies. Then MoveConstructible means you can perform the move operation, not (necessarily) that T has a move constructor.
I think has_move_constructor could be just "is_movable" (in the emulation library "is_movable" means "this type has activated move emulation", the T(rv<T> &) overload).
I expected something like that to be the case for emulated move.
For compilers with rvalue references, I'm not a language expert so I need someone that could write such a trait (can we easily detect if a type has the T(T&&t) constructor?).
There's no known way to do it (even with C++0x as currently defined). Unless someone comes up with an amazing hack, we need a new language feature.
For compilers with rvalue reference, if all types in the course are going to use the portable syntax (that is, they are going to define BOOST_HAS_MOVE_EMULATION macro) BOOST_HAS_MOVE_EMULATION can be used to put a typedef that will mark those types as having a move constructor.
Yep, that sounds like a great idea. And, failing that, the trait can be specialized.
Do you also want me to tweak container/detail/pair.hpp implementation and apply SFINAE for move constructors?
If possible. I suspect it applies not just to pair, but a bunch of others, too. Consider containers, which contain allocators.
I can do some work tomorrow (the trait), and commit it to sandbox.
Anything you can do would be much appreciated! -- Dave Abrahams BoostPro Computing http://www.boostpro.com