簡體   English   中英

為什么我不能使用 std::map[ ] 添加字符串,但 std::map.at() 有效?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM