如何在没有编译器警告的情况下返回对空字符串的 const 引用?

How can I return a const reference to an empty string without a compiler warning?

本文关键字:字符串 const 引用 返回 情况下 编译器 警告      更新时间:2023-10-16

我有一个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::string是可以的,因为你会在函数局部变量之外构造一个新字符串,但是当你返回一个std::string&时,你会使用局部变量。

但是当你返回一个静态值时,只需将其设为静态:

const std::string& GetString(int key)
{
static const string empty = "";
auto iterator = map.find(key);
if (iterator == map.end())
{
return empty;
}
return iterator->second;
}

我会将返回类型更改为std::string(因此返回空字符串是可以的)或std::string *(返回未找到的nullptr)。

否则编译器是正确的:你不能返回对即将被取消的本地对象的引用

相关文章: