
on Sun Oct 28 2012, Ion Gaztañaga <igaztanaga-AT-gmail.com> wrote:
Best,
Ion
El 27/10/2012 0:53, Dave Abrahams escribió:
4. This sentence doesn't make any sense to me; it needs clarification. I would make a suggestion, but, well, I don't understand what you're trying to say
The last one has the same behaviour as std::uninitialized_copy but since several standand library implementations don't play very well with move_iterators, this version is a portable version for those willing to use move iterators.
4. Using move iterator with C++03 compilers lead to compile errors. Some MSVC versions use a "_Construct" function that wraps placement new. And that funcion takes the argument as a const reference.
// TEMPLATE FUNCTION _Construct template<class _T1, class _T2> inline void _Construct(_T1 *_Ptr, const _T2& _Val) { new (_Ptr) _T1(_Val); }
then the copy constructor is called instead of the move constructor, making std::unitialized_copy unusable for move-only types. boost::unitialized_copy just tries to avoid this problem so that we can write portable code for C++03+Boost.Move and C++11 compilers. Any suggestion is welcome.
That doesn't explain the sentence, I'm afraid. For example, what does move_iterator have to do with any of this? It sounds like you're probably exposing implementation details by mentioning it at all, and if you *did* implement an algorithm by using move_iterator with a standard algorithm, you should change that, because you have no right to expect it to work even in C++11.
5. The section on constructor forwarding seems to imply that constructors are the only thing that will be forwarded, when of course that's not the case.
5. I know, but I couldn't find a generic solution for perfect forwarding and forwarding for constructors were an important use case, specially to implement containers with move semantics for C++03 compilers. Open to suggestions and changes.
I don't see why your solution for constructor forwarding couldn't apply equally well everywhere (since it doesn't really do anything other than pass-by-T const& AFAICT).
6. These sentences don't make sense to me together. They have no obvious connection to one another. To which limitations are you referring?
Fortunately, most constructors take arguments by value, by const-reference or by rvalue reference. If these limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads. This library makes this emulation easy with the help of BOOST_FWD_REF and boost::forward
As far as I can tell from the implementation, BOOST_FWD_REF just generates a const& in emulation mode, which isn't much of an emulation at all.
6. If you limit yourself to constructors taking const references or rvalue references (that if you avoid non-const reference or const rvalue reference arguments in constructors)
This doesn't make any sense to me either. Just in case our wires are crossed on this part: arguments are what you pass to functions. They are lvalues, glvalues, xvalues, rvalues and prvalues. Parameters are what a function receives; they can be references.
then this approach works reasonably well. You only need to write N overloads to implement emplace functions (as we have no variadic templates):
emplace();
template<class Arg1> emplace(BOOST_FWD_REF(Arg1) arg1)
template<class Arg1, class Arg2> emplace(BOOST_FWD_REF(Arg2) arg2)
//...
Just as you need to implement emplace for compilers with rvalue references but no variadic templates (like recent MSVC versions)
emplace();
template<class Arg1> emplace(Arg1 && arg1)
template<class Arg1, class Arg2> emplace(Arg2 &&arg1, Arg2 &&arg2)
//...
Catching by const T & works because it catches also rv<T> types, that are treated specially by move() and forward() emulation functions to emulate forwarding.
I don't see why this wouldn't "work" just as well for non-constructors, provided you're willing to accept the same limitations on their parameter types in C++03. -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost