考虑以下代码:
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
返回一个const引用:
https://en.cppreference.com/w/cpp/container/unordered_map/at
因此,如果我引用了unordered_map::at
的返回值,那我就不能修改其内容,对吗?还是我完全误解了const return的含义?据我了解,该代码甚至不应该编译。
现在,如果将std::string&
更改为std::string
,我将看到复制构造函数按预期执行。该程序将打印123hi, 123
,表明映射中包含的值未修改。
这里有两个问题:
std::move(x)
(引用string& x
的原始声明),则移动将按预期进行,或者最终完成会因为const引用而变成副本构造函数?答案 0 :(得分:14)
unordered_map::at
返回const引用
不,不是。它有两个重载:一个const,一个没有。您正在使用非常量重载。
答案 1 :(得分:7)
std::unordered_set::at
有两个重载,一个重载为const
限定的实例,一个重载为非const
限定的实例。一个重载确实返回了a。不可修改的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
版本const
的返回值甚至无法绑定到非std::unordered_set::at
引用,更不用说对该引用进行修改了。