如何解决为什么我不能使用 std::map[ ] 添加字符串,但 std::map.at() 有效?
我的问题是为什么 s += t.getM()[0];在示例代码 raise
main.cpp:44:20: error: passing ‘const std::map >’ as ‘this’ argument discards qualifiers [-fpermissive]
我检查了 cppreference,它说两者都返回一个引用。
此外,为什么 operator[] 和 .at() 都适用于 std::vector?
示例代码在这里。
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
class test {
public:
test(string str) {
vec.push_back(str);
mp[0] = str;
}
const vector<string>& getV() const {
return vec;
}
const map<int,string>& getM() const {
return mp;
}
private:
vector<string> vec;
map<int,string> mp;
};
int main()
{
string s;
test t("hello ");
s += t.getV().at(0);
s += t.getV()[0];
s += t.getM().at(0);
s += t.getM()[0];
cout << s;
}
解决方法
std::map::operator[]
仅适用于非const
std::map
。 The documentation on std::map::operator[]
很好地解释了这一点。这是页面开头的摘录:
返回对映射到与 key 等效的键的值的引用,如果这样的键不存在,则执行插入。
如您所见,如果键不存在,它会在映射中插入一个新的键/值对。显然,这不适用于 const
映射,因为您无法将元素插入其中,因为它们是不可变的。为什么不创建新值的运算符没有 const
重载,我不知道。但事情就是这样。
std::map::at()
,但与 std::map::operator[]
不完全一样。同样,摘自 documentation of std::map::at()
:
返回对元素映射值的引用,其键等效于键。如果不存在这样的元素,则抛出 std::out_of_range
类型的异常。
此外,该函数也有一个 const
重载:const T& at(const Key& key) const;
所以它可以用于 const
地图。
此外,为什么 operator[] 和 .at() 都适用于 std::vector?
因为 std::vector::operator[]
和 std::vector::at()
的工作方式非常相似,除了 std::vector::at()
进行边界检查而 std::vector::operator[]
没有。两者都不会创建新值(因为这不是向量的工作方式)并且都具有 const
重载。事实上,std::vector::operator[]
的文档甚至解决了它与 std::map::operator[]
之间的区别:
与 std::map::operator[]
不同,此运算符从不向容器中插入新元素。通过此运算符访问不存在的元素是未定义的行为。
(这是未定义的行为,因为正如我之前提到的,operator[]
不进行边界检查。)
只是为了添加到 @mediocrevegetable1's answer above,以下增加了容器的大小:
class test {
public:
...
map<int,string>& getM() {
return mp;
}
private:
...
}
int main()
{
string s;
test t("hello ");
s += t.getV().at(0);
s += t.getV()[0];
s += t.getM().at(0);
s += t.getM()[0];
cout << s;
cout << t.getM().size() << endl; // prints 1
auto temp = t.getM()[1]; // Key=1 does not exist in the container and hence is added
cout << t.getM().size() << endl; // prints 2
}
另外,我从 clang 而不是 gcc 得到了关于这个问题的更好提示:
no viable overloaded operator[] for type 'const map<int,std::string>' (aka 'const map<int,basic_string<char> >')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。