内部移动std::vector元素和QVector

Internal moving std::vector elements and QVector

本文关键字:QVector 元素 vector std 内部 移动      更新时间:2023-10-16

有两个向量std :: vectorQVector。我们必须检查插入元素时"移位"的方式。(是构造两个向量与五个元素和插入零元素)我有这个代码:

#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标志?

因为你的移动操作符可以抛出一个异常,std::vector不能使用它。如果操作符在调整大小过程的中途抛出异常,该怎么办?如果不能抛出异常,则声明为noexcept,并且vector实现可以使用它。

可能对某人有用。

struct MoveTest
{
    int i;
    MoveTest()                      {}
    MoveTest(MoveTest&&) noexcept   {std::cout << "constr moven";}
    MoveTest(const MoveTest&)       {std::cout << "constr copyn";}
    ~MoveTest() noexcept            {}
    MoveTest&   operator=   (MoveTest&&) noexcept   {std::cout << "moven"; return *this;}
    MoveTest&   operator=   (const MoveTest&)       {std::cout << "copyn"; 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

QT中的容器肯定能够处理移动语义。运行下面的例子,自己看看。

#include <QCoreApplication>
#include <QVector>
#include <iostream>
struct MoveTest
{
    int i;
    MoveTest()                      {}
    MoveTest(MoveTest&&) noexcept   {std::cout << "constr moven";}
    MoveTest(const MoveTest&)       {std::cout << "constr copyn";}
    ~MoveTest() noexcept            {}
    MoveTest&   operator=   (MoveTest&&) noexcept   {std::cout << "moven"; return *this;}
    MoveTest&   operator=   (const MoveTest&)       {std::cout << "copyn"; 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...