Consider this code:
std::unordered_map<std::string, std::string> test;
test.insert(std::unordered_map<std::string, std::string>::value_type("test", "123"));
std::string& x = test.at("test");
x += "hi";
std::cout << x << ", " << test.at("test") << std::endl;
This code prints "123hi, 123hi", as expected.
This is counter-intuitive, because unordered_map::at
returns a const reference: https://en.cppreference.com/w/cpp/container/unordered_map/at
So, if I make a reference to the return of unordered_map::at
, I shouldn't be able to modify its contents, correct? Or have I completely misunderstood the meaning of const returns? The way I understand it, this code shouldn't even compile.
Now, if I change std::string&
to std::string
, I see the copy constructor executed as expected. The program prints 123hi, 123
, showing that the value contained in the map is not modified.
Two questions here:
std::move(x)
(referring to the original declaration of string& x
) would the move be carried out as expected, or does it ultimately turn into a copy constructor because of the const reference?
unordered_map::at
returns a const reference
No, it doesn't. It has two overloads: one const, one not. You are using the non-const overload.
std::unordered_set::at
has two overloads, one for const
-qualified and one for non- const
-qualified instances.The one for const
-qualified instances does indeed return a non-modifiable const
reference. Try this:
const std::unordered_map<std::string, std::string> test = {{"test", "123"}};
// ^^ Note the const-specifier
std::string& x = test.at("test"); // No way, compiler will complain
This example shows that the return value of the const
version of std::unordered_set::at
can't even bind to a non- const
reference, let alone that reference being modified.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.