简体   繁体   中英

Why can I modify a const return-by-reference?

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:

  1. Why can I modify a const reference?
  2. If I were to use the string x to execute a move operation, such as 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM