传递const Key_Type&到std :: map的operator []

时间:2014-07-28 07:28:08

标签: c++ map std

为什么我无法将const Key_Type&传递给std :: map的operator []?我已完成此操作并已编译但在运行时std::bad_alloc抛出了异常:

std::map<std::string, int> myMap;

const std::string& f(const std::string& groupA, const std::string& groupB) 
{ 
    return groupA > groupB ? groupA + groupB : groupB + groupA;
}

std::cout << myMap[f("a", "b")];

2 个答案:

答案 0 :(得分:3)

您正在返回对临时函数const std::string& f(const std::string& groupA, const std::string& groupB)

的引用
return groupA > groupB ? groupA + groupB : groupB + groupA;

+运算符返回一个临时值,然后通过引用返回该值。

因此,按值(const std::string)更改返回类型返回可以解决问题。

正如@Narek所指出的,Herb Sutter如何使用const ref来解释临时变量。但是我们所遇到的问题陈述与Sutter所讨论的不符。为了解释更多,我创建了一个小程序。该计划解释了问题和解决方案:

#include <iostream>
#include <map>

/*
std::map<std::string, int> myMap;

const std::string& f(const std::string& groupA, const std::string& groupB) 
{ 
    return groupA > groupB ? groupA + groupB : groupB + groupA;
}*/


struct X{

  int member;


  X():member(0){
      std::cout<<"X ctr "<<std::endl;
  }

  X(const X& rhs){

      std::cout<<"X copy ctr "<<std::endl;
  }

  ~X(){

      std::cout<<"X dtr"<<std::endl;
      member = -1;
  }
};

void f2(const X& obj){

    std::cout<<"func "<<obj.member<<std::endl;

}   

const X& f3(){ 
    return X(); 
}

X f4(){ 
    return X(); //ideally not a good idea, exception is
    //http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
}

int main()
{
    /*  myMap["ba"] = 1;
    std::cout <<"key "<< f("a", "b")<<std::endl;
    std::cout << myMap[f("a", "b")]<<std::endl;*/

    std::cout << "-----Faulty Case-----------"<<std::endl;

    //reference returned by f3 is local to f3 call and 
    //is destructed as soon as f3() is out of stack
    //and hence the reference in f2() is not valid
    f2( f3() );

    std::cout <<std::endl<< "-----Correct way-----------"<<std::endl;

    //A temporary object is returned by f4 which is then referred by reference in f2.
    //This reference is alive in stack of f2 and hence can be used inside 
    //f2 with valid results.
    //As explained in following article, the refernce should remain
    //alive in stack to use temporary objects.
    //http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
    f2( f4() );

    //note in previous expression, f4 returns by value but still copy ctr is not invoked,
    //this I believe is Return Value Optimization (might be compiler dependent)

    return 0;
}

该计划的输出:

main.cpp: In function �const X& f3()�:
main.cpp:41:14: warning: returning reference to temporary [-Wreturn-local-addr]
     return X(); 
              ^

Executing the program....
$demo 
-----Faulty Case-----------
X ctr 
X dtr
func -1

-----Correct way-----------
X ctr 
func 0
X dtr

我希望这能清除云层。

答案 1 :(得分:0)

将f的定义从const std::string& f更改为const std::string f可以解决问题,因为这样(A + B)的临时结果会被复制到返回变量中。否则返回指向临时变量的指针,分配的内存的所有权定义不明确,并且出现问题。