为什么我可以通过引用修改常量返回



考虑以下代码:

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;

此代码按预期打印"123hi,123hi"。

这与直觉相反,因为unordered_map::at返回一个常量引用:https://en.cppreference.com/w/cpp/container/unordered_map/at

所以,如果我引用unordered_map::at的返回,我应该无法修改它的内容,对吗?还是我完全误解了const返回的含义?按照我的理解,这段代码甚至不应该编译。

现在,如果我将std::string&更改为std::string,我会看到复制构造函数按预期执行。程序打印123hi, 123,表示映射中包含的值未被修改。

这里有两个问题:

  1. 为什么我可以修改常量引用
  2. 如果我使用字符串x来执行移动操作,例如std::move(x)(指string& x的原始声明(,移动会按预期执行吗?还是因为const引用而最终变成了复制构造函数

unordered_map::at返回常量引用

不,不是。它有两个重载:一个是const,一个不是。您正在使用非常量重载。

std::unordered_set::at有两个重载,一个用于符合const条件的实例,另一个用于不符合const条件的实例。const限定实例的引用确实返回了一个不可修改的const引用。试试这个:

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

此示例显示std::unordered_set::atconst版本的返回值甚至不能绑定到非const引用,更不用说正在修改的引用了。

相关内容

  • 没有找到相关文章