Internal moving elements std :: vector and QVector

There are two vectors std :: vector and QVector . We need to check how to "shift" the elements when pasting. (I built two vectors with five elements and inserted the zero element) I have this code:

 #include <QVector> #include <QTextStream> struct MoveTest { int i; MoveTest() {} MoveTest(const MoveTest& other) {QTextStream(stdout) << "constr copy" << endl;} MoveTest(MoveTest &&other) {QTextStream(stdout) << "constr move" << endl;} ~MoveTest() {} inline MoveTest& operator= (const MoveTest& other) {QTextStream(stdout) << "copy" << endl;} inline MoveTest& operator= (MoveTest &&other) {QTextStream(stdout) << "move" << endl;} }; int main(int argc, char *argv[]) { QTextStream(stdout) << "std::move:" << endl; MoveTest t1; MoveTest t2(std::move(t1)); t1 = std::move(t2); QTextStream(stdout) << "QVector:" << endl; QVector<MoveTest> qmTest(5); qmTest.insert(qmTest.begin(), MoveTest()); QTextStream(stdout) << "std::vector:" << endl; std::vector<MoveTest> mTest(5); mTest.insert(mTest.begin(), MoveTest()); return 0; } 

My conclusion with gcc 4.7.2, QMAKE_CXXFLAGS + = -std = C ++ 0x:

 std::move: constr move move QVector: constr copy constr copy constr copy constr copy constr copy constr copy copy copy copy copy copy copy std::vector: constr move constr copy constr copy constr copy constr copy constr copy 

How to paste elements with internal offset without copying? What GCC flags are needed?

+7
source share
3 answers

Since your move statement can throw an exception, std::vector cannot use it. What would he do if the operator threw an exception halfway through the resize process? Declare it noexcept if it cannot throw an exception, and the vector implementation can use it.

+5
source

May be helpful to someone.

 struct MoveTest { int i; MoveTest() {} MoveTest(MoveTest&&) noexcept {std::cout << "constr move\n";} MoveTest(const MoveTest&) {std::cout << "constr copy\n";} ~MoveTest() noexcept {} MoveTest& operator= (MoveTest&&) noexcept {std::cout << "move\n"; return *this;} MoveTest& operator= (const MoveTest&) {std::cout << "copy\n"; return *this;} }; Q_DECLARE_TYPEINFO(MoveTest, Q_MOVABLE_TYPE); int main(int argc, char *argv[]) { std::cout << "std::move:\n"; MoveTest t1; MoveTest t2(std::move(t1)); MoveTest t3(std::move_if_noexcept(t2)); t2 = std::move(t3); t1 = std::move_if_noexcept(t2); std::cout << "\n"; std::cout << "QVector:\n"; QVector<MoveTest> qmTest(5); qmTest.insert(qmTest.begin(), MoveTest()); std::cout << "\n"; std::cout << "std::vector:\n"; std::vector<MoveTest> mTest(5); mTest.insert(mTest.begin(), MoveTest()); return 0; } 

Of:

 std::move: constr move constr move move move QVector: constr copy constr copy std::vector: constr move constr move constr move constr move constr move constr move 
+1
source

Of course, containers in QT are able to handle the semantics of movement. Follow the example below and see for yourself.

 #include <QCoreApplication> #include <QVector> #include <iostream> struct MoveTest { int i; MoveTest() {} MoveTest(MoveTest&&) noexcept {std::cout << "constr move\n";} MoveTest(const MoveTest&) {std::cout << "constr copy\n";} ~MoveTest() noexcept {} MoveTest& operator= (MoveTest&&) noexcept {std::cout << "move\n"; return *this;} MoveTest& operator= (const MoveTest&) {std::cout << "copy\n"; return *this;} }; Q_DECLARE_TYPEINFO(MoveTest, Q_MOVABLE_TYPE); int main(int argc, char *argv[]) { std::cout << "std::move:\n"; MoveTest t1; MoveTest t2(std::move(t1)); MoveTest t3(std::move_if_noexcept(t2)); t2 = std::move(t3); t1 = std::move_if_noexcept(t2); std::cout << "\n"; std::cout << "QVector:\n"; QVector<MoveTest> qmTest; int i=5; while(i) { qmTest.append(MoveTest()); --i; } std::cout << "\n"; std::cout << "std::vector:\n"; std::vector<MoveTest> mTest(5); mTest.insert(mTest.begin(), MoveTest()); return 0; } 

Since two objects have the same use, this does not mean that all member functions are the same. Check out the output below. Exit:

 std::move: constr move constr move move move QVector: constr move constr move constr move constr move constr move std::vector: constr move constr move constr move constr move constr move constr move Press <RETURN> to close this window... 
0
source

All Articles