首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11向量在rvalue上复制

C++11向量在rvalue上复制
EN

Stack Overflow用户
提问于 2017-04-05 15:02:16
回答 1查看 1.2K关注 0票数 10

我在std::向量上有一些奇怪的行为,添加了rvalue:

代码语言:javascript
复制
#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;
}

产出如下:

代码语言:javascript
复制
default
moved 
default
moved 
copied!

所以向量仍然创建A的副本,我做的越多,我得到的拷贝就越多。但是,如果我用默认的A(A &data) = default;或delete复制构造函数替换A(const &data)= delete;,则在没有复制的情况下得到正确的结果。如果我第一次调用具有足够大小的datavec.reserve,我也没有副本。我使用gcc版本5.4.0,没有具体的参数

代码语言:javascript
复制
g++ -std=c++11 -o main ../main.cpp

你对为什么向量复制明显的rvalue有任何想法吗?我希望这不是STL的错误

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-05 15:05:27

std::vector在内部缓冲区重新分配期间复制元素。它选择复制而不是移动,因为移动构造函数没有标记为noexcept。标记它..。

代码语言:javascript
复制
A(A &&) noexcept {      std::cout << "moved " << std::endl; }

...will解决了这个问题。

告诉编译器移动构造函数不会抛出允许std::vector的实现在内部重新分配期间移动,从而满足C++标准所要求的异常保证。

或者,您可以提前std::vector::reserve容器以防止内部缓冲区的增长。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43234946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档