此简单代码:
#include <iostream>
#include <vector>
struct my_struct
{
int m_a;
my_struct(int a) : m_a(a) { std::cout << "normal const " << m_a << std::endl; }
my_struct(const my_struct&& other) : m_a(other.m_a) { std::cout << "copy move " << other.m_a << std::endl; }
my_struct(const my_struct &other) : m_a(other.m_a) { std::cout << "copy const " << other.m_a << std::endl; }
};
class my_class
{
public:
my_class() {}
void append(my_struct &&m) { m_vec.push_back(m); }
private:
std::vector<my_struct> m_vec;
};
int main()
{
my_class m;
m.append(my_struct(5));
m.append(std::move(my_struct(6)));
}
产生此输出:
normal const 5
copy const 5
normal const 6
copy const 6
copy const 5
第一次追加请求将创建对象,而push_back将创建一个副本。同样,第二个追加请求创建对象,而push_back创建副本。现在,第一个对象的副本构造函数被神秘地调用。有人可以解释一下会发生什么吗?看起来像是一个奇怪的副作用...
现在,神秘地调用了第一个对象的副本构造函数。有人可以解释一下会发生什么吗?看起来像是一个奇怪的副作用...
[当您在push_back上调用std::vector时,矢量可能需要增大其大小,如cppreference中所述:
如果新的size()大于Capacity(),则所有迭代器和引用(包括过去的迭代器)都将失效。否则,只有过去的迭代器才无效。
您可以在将任何内容推入向量之前使用reserve。试试这个:
class my_class
{
public:
my_class()
{
m_vec.reserve(10); // Use any number that you want.
}
void append(my_struct &&m) { m_vec.push_back(m); }
private:
std::vector<my_struct> m_vec;
};
[另外,您需要修复move构造函数的签名,因为move构造函数需要rvalue
引用(更具体地说,是xvalue或prvalue)。它应该像这样:
my_struct(my_struct&& other) : m_a(other.m_a) { std::cout << "copy move " << other.m_a << std::endl; }