[英]Why I can't use the std::map[ ] to add a string, but std::map.at() works?
我的問題是為什么 s += t.getM()[0]; 在示例代碼中
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[]
僅適用於非常std::map
const
std::map::operator[]
上的文檔很好地解釋了這一點。 這是頁面開頭的摘錄:
返回對映射到與 key 等效的鍵的值的引用,如果這樣的鍵不存在,則執行插入。
如您所見,如果該鍵不存在,它會將一個新的鍵/值對插入 map。 顯然,這不適用於const
映射,因為您不能將元素插入其中,因為它們是不可變的。 為什么不存在不會創建新值的運算符的const
重載,我不知道。 但事實就是如此。
std::map::at()
,但是與std::map::operator[]
的工作方式不同。 同樣,摘自std::map::at()
的文檔:
返回對元素的映射值的引用,其 key 等效於 key。 如果不存在這樣的元素,則拋出
std::out_of_range
類型的異常。
此外,function 也有一個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 的答案,以下增加了容器的大小:
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> >')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.