Home > Enterprise >  How can I change map 's second component?
How can I change map 's second component?

Time:05-15

#include <iostream>
#include <map> 
using namespace std;
 
int main() {
    map<int, int> ma;
 
    //   원소를 추가 하자!!
    ma.insert(make_pair(100, 2));  // key 값 : 1 , value : 3
    ma.insert(make_pair(101, 3)); // key 값 : 3,  value : 13
    ma.insert(make_pair(102, 2)); // key 값 : 3,  value : 13
    ma.insert(make_pair(103, 3)); // key 값 : 3,  value : 13
    ma.insert(make_pair(104, 1)); // key 값 : 3,  value : 13
 
    // make_pair 형식으로 저장 했으므로
    // key 값은 fisrt 로 접근 value 값은 second 로 접근한다.
    for (auto iter : ma) {
        cout << "key : " << iter.first << " value : " << iter.second << '\n';
    iter.second = iter.second   1;
    }
    cout << "\n" << "\n";
 
    for (auto iter : ma) {
        cout << "key : " << iter.first << " value : " << iter.second << '\n';
    }

    cout << "\n" << "\n";
    return 0;
}

Actually , I want to change the value of second component of pair.

iter.second = iter.second   1;

This code can't change the thing... How can I change ???

CodePudding user response:

The auto keyword in C always tries to infer a non-reference type, so in your case it infers iter as being type std::pair<const int, int>. This is not a reference type, so the values from the map get copied into the iter variable, and so any changes made to iter are not reflected in the map itself.

You can write auto& instead to force an lvalue-reference type:

for (auto& iter : ma) { // <-- Notice ampersand here
  iter.second = iter.second   1;
}

CodePudding user response:

Your main problem is that you called the variable "iter" so you must think it is an iterator of some sort. If it were an iterator, your code would work fine:

#include <iostream>
#include <map>

int main() {
    std::map<int, int> map {
        {100, 2}, {101, 3}, {102, 2}, {103, 3}, {104, 1},
    };

    for (auto iter = map.begin(), end = map.end(); iter != end;   iter) {
        std::cout << "key : " << iter->first << " value : " << iter->second << '\n';
          (iter->second);
    }

    std::cout << "\n\n";

    for (auto iter = map.begin(), end = map.end(); iter != end;   iter) {
        std::cout << "key : " << iter->first << " value : " << iter->second << '\n';
    }

    std::cout << "\n\n";
}

(See online)

But since you are using a range-based for loop you are accessing the values themselves, not an iterator to them. In that case, if you use auto you are getting a copy of the elements, and any changes you make are done the copies, not the elements themselves. If you instead use auto& you will get a reference instead, which is what you want:

#include <iostream>
#include <map>

int main() {
    std::map<int, int> map {
        {100, 2}, {101, 3}, {102, 2}, {103, 3}, {104, 1},
    };

    for (auto& [key, val] : map) {
        std::cout << "key : " << key << " value : " << val << '\n';
          val;
    }

    std::cout << "\n\n";

    for (auto& [key, val] : map) {
        std::cout << "key : " << key << " value : " << val << '\n';
    }

    std::cout << "\n\n";
}

(See online)

Do note the use of structured bindings to simplify the code.

  • Related