C++11 向量在右值上进行复制
C++11 vector makes copies on rvalue
我在 std::vector 上添加右值时出现一些奇怪的行为:
#include <iostream>
#include <vector>
class A {
public:
A():i_{5}{std::cout << "default" << std::endl;}
A(const A &data) { std::cout << "copied!" << std::endl; }
A(A &&data) { std::cout << "moved " << std::endl; }
int i_;
};
int main(int argc, char *argv[]) {
std::vector<A> datavec;
datavec.push_back(A{});
datavec.push_back(A{});
return 0;
}
输出为:
default
moved
default
moved
copied!
所以 vector 仍然创建 A 的副本,我做的越多 - 我得到的副本越多。
但是,如果我用默认 A(A &&data) = default; 替换移动构造函数或用 A(const A &data) = delete;[=23 删除复制构造函数=] 我在没有复制的情况下得到正确的结果。如果我第一次调用 datavec.reserve 足够大,我也没有副本。
我使用没有特定参数的 gcc 版本 5.4.0
g++ -std=c++11 -o main ../main.cpp
你有没有想过为什么 vector 会复制明显的右值?希望不是STL的bug
std::vector
正在内部缓冲区重新分配 期间复制您的元素。它选择复制而不是移动,因为您的移动构造函数未标记 noexcept
。标记它...
A(A &&) noexcept { std::cout << "moved " << std::endl; }
...将解决此问题。
告诉编译器你的移动构造函数不会抛出允许std::vector
的实现在内部重新分配期间移动,实现异常保证 C++ 标准要求。
或者,您可以提前std::vector::reserve
您的容器以防止内部缓冲区的增长。
我在 std::vector 上添加右值时出现一些奇怪的行为:
#include <iostream>
#include <vector>
class A {
public:
A():i_{5}{std::cout << "default" << std::endl;}
A(const A &data) { std::cout << "copied!" << std::endl; }
A(A &&data) { std::cout << "moved " << std::endl; }
int i_;
};
int main(int argc, char *argv[]) {
std::vector<A> datavec;
datavec.push_back(A{});
datavec.push_back(A{});
return 0;
}
输出为:
default
moved
default
moved
copied!
所以 vector 仍然创建 A 的副本,我做的越多 - 我得到的副本越多。 但是,如果我用默认 A(A &&data) = default; 替换移动构造函数或用 A(const A &data) = delete;[=23 删除复制构造函数=] 我在没有复制的情况下得到正确的结果。如果我第一次调用 datavec.reserve 足够大,我也没有副本。 我使用没有特定参数的 gcc 版本 5.4.0
g++ -std=c++11 -o main ../main.cpp
你有没有想过为什么 vector 会复制明显的右值?希望不是STL的bug
std::vector
正在内部缓冲区重新分配 期间复制您的元素。它选择复制而不是移动,因为您的移动构造函数未标记 noexcept
。标记它...
A(A &&) noexcept { std::cout << "moved " << std::endl; }
...将解决此问题。
告诉编译器你的移动构造函数不会抛出允许std::vector
的实现在内部重新分配期间移动,实现异常保证 C++ 标准要求。
或者,您可以提前std::vector::reserve
您的容器以防止内部缓冲区的增长。