首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将空初始化程序列表分配给现有向量或映射的效果?

将空初始化程序列表分配给现有向量或映射的效果?
EN

Stack Overflow用户
提问于 2017-06-08 16:44:44
回答 2查看 335关注 0票数 1

我有两个容器,a std::vectorstd::map

代码语言:javascript
复制
vector<int> my_vector;
map<string,int> my_map;
my_vector.push_back(3);

// elaboration of my_vector;
...

my_map["Hello"] = 1;

// elaboration of my_map
...

后来我做了:

代码语言:javascript
复制
my_map = {};
my_vector = {};

这会使两个容器变成两个空容器,对吗?此外,以前从my_mapmy_vector指向的内存发生了什么情况?

(我在C++11上)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-08 17:18:40

是的,这两个作业都会导致向量和地图被清空。这两个赋值在向量和映射的大小上都是线性的,因为两者都要求在赋值之前销毁容器中的每个元素,而这需要O(n)遍历。向量重用内存(https://wandbox.org/permlink/eIJEcEqERC2ybAjU)我认为映射重用内存是否已定义(或者至少我无法从文档中看出)

至于棘手的部分(在我看来),这里叫哪个赋值操作符?是初始化程序列表中的赋值操作符,还是向量和映射的移动赋值运算符(因为{}隐式地可转换为两者之一的实例)。我在这里找到了这个引用,assignment

注意,如果某个非类类型的非模板赋值运算符可用,那么它比E1 = {}中的复制/移动赋值更好,因为{}到非类是身份转换,它比用户定义的从{}到类类型的转换要高。

因此,如果有一个非模板赋值操作符,std::vector确实有。这比模板化的std::intializer_list赋值运算符中的赋值运算符更可取。您只需检查接口,以了解发生了什么。你可以在这里看到同样的东西

代码语言:javascript
复制
#include <initializer_list>
#include <iostream>
#include <string>
#include <vector>
#include <map>

using std::cout;
using std::endl;
using std::string;

class Something {
public:
    Something() {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    template <typename U>
    Something(std::initializer_list<U>) {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    Something& operator=(const Something&) {
        cout << __PRETTY_FUNCTION__ << endl;
        return *this;
    }
    Something& operator=(Something&&) {
        cout << __PRETTY_FUNCTION__ << endl;
        return *this;
    }
    Something(const Something&) {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    Something(Something&&) {
        cout << __PRETTY_FUNCTION__ << endl;
    }
    template <typename U>
    Something& operator=(std::initializer_list<U>) {
        cout << __PRETTY_FUNCTION__ << endl;
        return *this;
    }

    // to silence unused variable warning
    int get_something() {
        return this->something;
    }
private:
    int something{1};
};

int main() {
    auto something = Something{};
    something = {};
    something = {1, 2, 3};
}

它的输出是

代码语言:javascript
复制
Something::Something()
Something::Something()
Something &Something::operator=(Something &&)
Something &Something::operator=(std::initializer_list<U>) [U = int]

请注意,上面的情况不是std::vector发生的情况,因为它的initializer_list赋值操作符不是模板,因此被调用。

票数 3
EN

Stack Overflow用户

发布于 2017-06-08 16:59:51

两个运算符都会将初始化程序列表中的值复制到容器中,如下所示。由于您的初始化程序列表为空,您的集合在复制赋值后将为空。

http://www.cplusplus.com/reference/vector/vector/operator=/ http://www.cplusplus.com/reference/map/map/operator=/

旧地图和向量被它们的副本赋值操作符破坏。“在调用之前存储在容器中的元素被分配给或销毁”,这是在这个帖子的注释中引用的。

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

https://stackoverflow.com/questions/44441387

复制
相关文章

相似问题

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