C ++向量emplace_back调用复制构造函数 [英] C++ vector emplace_back calls copy constructor

查看:59
本文介绍了C ++向量emplace_back调用复制构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个演示课程。我不想复制我的类,所以我删除了复制构造函数。我希望vector.emplace_back使用此构造函数 MyClass(类型类型)。但是这些代码无法编译。为什么?

This is a demo class. I do not want my class to be copied, so I delete the copy constructor. I want vector.emplace_back to use this constructor 'MyClass(Type type)'. But these codes won't compile. Why?

class MyClass
{
public:
    typedef enum
    {
        e1,
        e2
    } Type;
private:
    Type _type;
    MyClass(const MyClass& other) = delete; // no copy
public:
    MyClass(): _type(e1) {};
    MyClass(Type type): _type(type) { /* the constructor I wanted. */ };
};

std::vector<MyClass> list;
list.emplace_back(MyClass::e1);
list.emplace_back(MyClass::e2);


推荐答案

vector ,以便它可以在需要增加存储量时复制该元素。

The copy constructor is required by vector so that it can copy the element when it need to grow its storage.

您可以阅读向量


T必须满足CopyAssignable和
CopyConstructible 的要求。 (直到C ++ 11)

T must meet the requirements of CopyAssignable and CopyConstructible. (until C++11)


施加的要求取决于在
容器上执行的实际操作。通常,要求元素类型是完整的
类型并满足Erasable的要求,但是许多成员函数
提出了更严格的要求。 (自C ++ 11起)(直到C ++ 17)

The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type is a complete type and meets the requirements of Erasable, but many member functions impose stricter requirements. (since C++11) (until C++17)

对元素施加的
要求取决于实际的
操作在容器上执行。通常,要求
元素类型满足Erasable的要求,但是许多成员
函数施加了更严格的要求。如果
分配器满足分配器完整性要求,则可以使用不完整的元素类型实例化此容器(但不包含其
成员)。

The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type meets the requirements of Erasable, but many member functions impose stricter requirements. This container (but not its members) can be instantiated with an incomplete element type if the allocator satisfies the allocator completeness requirements.

某些日志记录可以帮助您了解发生了什么情况

Some logging can help you understand what's going on

对于此代码

class MyClass
{
public:
    typedef enum
    {
        e1 = 1,
        e2 = 2,
        e3 = 3,
    } Type;
private:
    Type _type;
public:
    MyClass(Type type): _type(type) { std::cout << "create " << type << "\n"; };
    MyClass(const MyClass& other) { std::cout << "copy " << other._type << "\n"; }
};

int main() {
    std::vector<MyClass> list;
    list.reserve(2);
    list.emplace_back(MyClass::e1);
    list.emplace_back(MyClass::e2);
    list.emplace_back(MyClass::e3);
}

输出为

create 1
create 2
create 3
copy 1
copy 2

因此您可以 emplace_back 确实使用所需的构造函数创建元素并在需要时调用复制构造函数增加存储空间。您可以预先调用具有足够容量的 reserve 来避免调用副本构造函数。

So you can emplace_back does use the desired constructor to create the element and call copy constructor when it need to grow the storage. You can call reserve with enough capacity upfront to avoid the need to call copy constructor.

如果出于某种原因您真的不希望它可以复制构造,则可以使用 std :: list 代替 std :: vector 作为 list 的实现是链接列表,它不需要移动元素。

If for some reason you really don't want it to be copy constructible, you can use std::list instead of std::vector as list is implemented as linked list, it doesn't need to move the elements.

http://coliru.stacked-crooked.com/a/16f93cfc6b2fc73c

这篇关于C ++向量emplace_back调用复制构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆