为什么我无法将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")];
答案 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)的临时结果会被复制到返回变量中。否则返回指向临时变量的指针,分配的内存的所有权定义不明确,并且出现问题。