将空初始化器列表分配给现有向量或地图的效果

Effect of assigning an empty initializer list to an existing vector or map?

本文关键字:向量 地图 初始化 列表 分配      更新时间:2023-10-16

我有2个容器,a std::vector和一个std::map

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
...

后来我这样做:

my_map = {};
my_vector = {};

这应该使2个容器2个空容器,对吗?此外,先前指向my_mapmy_vector的内存会发生什么?

(我在C 11(

是的,这两个作业都导致向量和地图被清空。两种分配均在向量和地图的大小上是线性的,因为两者都需要在分配之前将容器中的每个元素销毁,并且需要O(n(遍历。向量重新恢复内存(https://wandbox.org/permlink/eijeceqerc2ybaju(,我认为是否已定义了映射的记忆(或者至少我无法从文档中解释(

>

至于棘手的部分(在我看来(,在这里称哪个任务运算符?是从初始化器列表中的分配运算符还是向量和地图的移动分配运算符(因为{}隐式转换为任何一个实例(。我从CPPReference找到了此报价。

请注意,如果可以使用某些非类型类型的非网板分配运算符,则优先于e1 = {}中的复制/移动分配,因为{}到非班级是一个身份转换,它会超出用户定义的转换从{}到类类型。

因此,如果有一个非模板分配运算符,std::vector确实具有。这比来自模板的std::intializer_list分配操作员的分配运算符优选。您只需要检查界面即可查看发生了什么。您可以在这里看到相同的

#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};
}

这是

的输出
Something::Something()
Something::Something()
Something &Something::operator=(Something &&)
Something &Something::operator=(std::initializer_list<U>) [U = int]

请注意,上述情况不是std::vector发生的情况,因为其initializer_list分配操作员不是模板,因此称为模板。

两个运算符两个操作员从初始化器列表中将值复制到您的容器中,如下所述。由于您的初始化器列表为空,因此您的收藏将在复制分配后为空。

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

您的旧地图和向量被其副本分配操作员破坏。"在呼叫之前存储在容器中的元素要么被分配给或销毁",如本文评论中所述。