关于c ++标准库容器中变量的范围

时间:2015-10-16 06:23:17

标签: c++

在评论中考虑以下函数:

map<vector<a>, b> func() {
    map<vector<a>, b> x;
    //add values of to x.
    return x;    //Everything gets copied and the local variable dies. Not good when your x is very big, lets say in MB s
}

map<vector<a>, b> *func() {
    map<vector<a>, b> *x;
    x = new map<vector<a>, b>(); //allocate the object.
    b _b;
    a random;
    vector<a> y;
    y.push_back(random);
    //add values of to x.
    x->insert(make_pair(y, _b));
    return x;    //Pointer is returned. Not sure what would happen to keys of map. Will they be copied again?
}

我对上图的另一个问题是find()的复杂性会怎样?我认为它应该与vector的默认比较器相同,用于相应地对元素进行排序。如果我错了,请纠正我。

map<vector<a> *, b> *func() {
    map<vector<a>, b> *x;
    x = new map<vector<a> *, b>(); //allocate the object.
    b b_;
    a random;
    vector<a> *y = vector<a>();
    y->push_back(random);
    //add values of to x.
    x->insert(make_pair(y, b_));
    return x;    //Pointer is returned. Not sure what would happen to the elements of the keys of the map. 
                 //In other words I mean will variable 'random' be copied again on function return. Will they be copied again?
}

2 个答案:

答案 0 :(得分:2)

您正在尝试过早优化,从而导致潜在的灾难。

return x,如果编译器优化是&#34; on&#34; (在编译器上使用-O3标志)并且编译器不是完全愚蠢的,不会产生副本。简单x将被分配到调用者堆栈空间并在函数内部引用。

你的第二次尝试(返回一个指针)有效,但是在适当的控制资源分配方面会产生问题:你在函数内调用new,但是应该调用delete的人和时间?可能使用智能指针(如std::unique_ptr)会有所帮助:当没有人再存储指针时,创建的地图将被删除。

你的第三次尝试根本行不通。

vector<a> *y = vector<a>();甚至无法编译(将vector<a>分配给vector<a>*?!?),然后地图将包含...指针作为键。除非您没有提供比较功能,否则地图将按照矢量的地址进行排序,而不是内容!没有人会照顾他们的毁灭。

你还会冒另一个风险:因为地图包含指针作为键,所以没有人授予矢量的常数:如果&#34;键&#34;那么,地图排序顺序的正确性会发生什么?由于这个功能的一些错误而被改变了?

答案 1 :(得分:0)

第一次尝试导致复制,但编译器将执行令人讨厌的优化工作,这可能是最常见的。不会有复制,但只是为了确定你可以写:

std::map<std::vector<a>,b> func() {
   return map<vector<a>, b>() ;
}

第二次尝试引导在堆上创建的对象。放置在容器内的对象将复制到

x->insert(make_pair(y,b));

因此它们的寿命与容器的寿命有关。

然后你负责删除指针上的地图调用删除,这不是最好的做法,但你会看到周围发生的事情。

当您调用map成员函数时,find的复杂性是对数的,如果在对象上调用静态版本,则为linear。您的密钥上最多将进行线性比较,这是一个向量。

第三次尝试使用指向向量的指针(需要新的)

std::vector<a> * y = new vector<a>;

基本上你应该在地图上修改你的密钥

std::map<vector<a> *, b> 

需要您修改func()的签名以适当地返回类型。

或取消引用该对象以进行复制

x->insert(make_pair(*y,_n));

结果是您还必须管理用于密钥的内存并根据需要逐个删除它们。真的胜过这个目的,只是尽量使用容器逻辑来自动管理内存。