From 5497183c71de352324cab05f3c0a768be75a236a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 15 May 2019 11:52:14 +0200 Subject: Add some examples to qExchange() docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I758782f6566ab94006aedacc9988ec4eb09a14c6 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Paul Wicking --- src/corelib/global/qglobal.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/corelib/global/qglobal.cpp') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 3436a19881..be01e5a605 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3815,7 +3815,46 @@ bool qunsetenv(const char *varName) This is Qt's implementation of std::exchange(). It differs from std::exchange() only in that it is \c constexpr already in C++14, and available on all supported compilers. + + Here is how to use qExchange() to implement move constructors: + \code + MyClass(MyClass &&other) + : m_pointer{qExchange(other.m_pointer, nullptr)}, + m_int{qExchange(other.m_int, 0)}, + m_vector{std::move(other.m_vector)}, + ... + \endcode + + For members of class type, we can use std::move(), as their move-constructor will + do the right thing. But for scalar types such as raw pointers or integer type, move + is the same as copy, which, particularly for pointers, is not what we expect. So, we + cannot use std::move() for such types, but we can use std::exchange()/qExchange() to + make sure the source object's member is already reset by the time we get to the + initialization of our next data member, which might come in handy if the constructor + exits with an exception. + + Here is how to use qExchange() to write a loop that consumes the collection it + iterates over: + \code + for (auto &e : qExchange(collection, {}) + doSomethingWith(e); + \endcode + + Which is equivalent to the following, much more verbose code: + \code + { + auto tmp = std::move(collection); + collection = {}; // or collection.clear() + for (auto &e : tmp) + doSomethingWith(e); + } // destroys 'tmp' + \endcode + + This is perfectly safe, as the for-loop keeps the result of qExchange() alive for as + long as the loop runs, saving the declaration of a temporary variable. Be aware, though, + that qExchange() returns a non-const object, so Qt containers may detach. */ + /*! \macro QT_TR_NOOP(sourceText) \relates -- cgit v1.2.3