有两个向量std :: vector
和QVector
。我们必须检查插入时“移位”元素的方式。 (构造了两个带有五个元素并插入零元素的向量)我有这段代码:
#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;
}
我的输出与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
如何在不复制的情况下插入具有内部移位的元素?需要什么GCC标志?
答案 0 :(得分:5)
由于您的move运算符可以抛出异常,std::vector
无法使用它。如果操作员在调整大小过程中途抛出异常,它会怎么做?如果它不能抛出异常并且向量实现可以使用它,则声明它为noexcept。
答案 1 :(得分:1)
可能对某人有用。
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;
}
输出:
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
答案 2 :(得分:0)
QT中的容器当然能够处理移动语义。运行下面的示例并亲自查看。
#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;
}
由于两个对象具有相似的用途,并不意味着所有成员函数都相同。检查下面的输出。 出:
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...