【发布时间】:2015-05-14 13:56:40
【问题描述】:
我有一个 std::unordered_map<int, std::string> 和一个函数 GetString(int key),它接受一个 int 键并从此映射返回一个字符串值。
当在地图中找不到键时,我必须返回一个空字符串。
#include <iostream>
#include <string>
#include <unordered_map>
std::unordered_map<int, std::string> map
{
{ 5, "somelongstring" }
};
const std::string& GetString(int key)
{
auto iterator = map.find(key);
if (iterator == map.end())
{
return "";
}
return iterator->second;
}
int main()
{
std::cout << GetString(1) << std::endl;
}
问题是编译器给了我这个警告
warning C4172: returning address of local variable or temporary
(使用 MS Visual Studio 2013)或
warning: returning reference to temporary [-Wreturn-local-addr]
(使用 g++ 4.9.2)
我发现摆脱这种情况的一种方法是在顶部声明 static const std::string 并返回它而不是空字符串文字
static const std::string Empty = "";
const std::string& GetString(int key)
{
auto iterator = map.find(key);
if (iterator == map.end())
{
return Empty;
}
return iterator->second;
}
但是定义一个空字符串字面量似乎不是很干净。有没有一种巧妙的方法来做到这一点?
更新:我的地图在启动期间被初始化一次,然后从多个线程同时读取(使用GetString)。使用函数静态空字符串不起作用,因为函数静态变量在 Visual Studio 的编译器下没有以线程安全的方式初始化。
【问题讨论】:
-
我认为
std::unordered_map与您的问题没有任何关系,真的。 -
const 字符串在函数中可以是静态的,而不是全局的。
-
我认为没有更好的解决方案。您需要一个
string实例,该实例在您返回引用时仍然有效,或者您自己返回一个string实例(不是引用),但这可能效率低下。 -
@einpoklum 文字是
const char[1]类型,要返回对std::string的引用,会创建一个临时文件,但您不能(合法)返回对临时文件的引用。跨度> -
@einpoklum 字面量不是
std::string。这是一个C字符串。要从此函数返回它,必须将其转换为std::string,在此过程中创建一个临时对象。返回对该临时对象的引用,就像它超出范围并被销毁一样。