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

I have std::unordered_map<int, std::string> and a GetString(int key) function that takes an int key and returns a string value from this map.

If the key is not found on the map, I must return an empty string.

 #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; } 

The problem is that the compiler gives me this warning

 warning C4172: returning address of local variable or temporary 

(with MS Visual Studio 2013) or

 warning: returning reference to temporary [-Wreturn-local-addr] 

(with g ++ 4.9.2)

One way I could get out of this I found was to declare a static const std::string at the top and return it instead of an empty string literal

 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; } 

But it was not very easy to define an empty string literal. Is there any way to do this?

Update. My card is initialized once during startup, and then is read from multiple threads simultaneously (using GetString ). Using a static empty string function will not work because static function variables are not initialized in a thread-safe way with the visual studio compiler.

+6
source share
2 answers

The warning message explicitly indicates what the problem is: you are returning the address of the local variable ( "" "), which will be freed from the stack after the function returns. It would be nice to return std::string because you built a new line outside the local variables of the function but as std::string& returns, you use a local variable.

But when you return a static value, just make it static:

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

I would change the return type to std::string (and therefore returning an empty string in order) or std::string * ( nullptr return for not found).

Otherwise, the compiler is right: you cannot return a link to a local object to be destroyed

+3
source

Source: https://habr.com/ru/post/987205/


All Articles