1

In the following code, [id, name] is a const reference. However, studentMap is non-const. The user can change the value of studentMap in the loop. I want to ask whether there is a way to make the StudentMap also const. Thanks.

#include <iostream>
#include <string>
#include <map>


int main() {
    std::map<int, std::string> studentMap;
    studentMap[1] = "Tom";
    studentMap[7] = "Jack";
    studentMap[15] = "John";

    for (const auto& [id, name] : studentMap) {
        studentMap.at(id) += "test";
    }

    for (const auto& [id, name]: studentMap) {
        std::cout << id << " " << name << "\n";
    }

    return 0;
}
2
  • You need studentMap to be non-const as you are setting that up before the loops. So, you could do something like creating a new scope (e.g. a new function), have a const ref referring to studentMap, and iterate thru that constStudentMap Commented May 5, 2022 at 3:33
  • 1
    You can also create a new variable instead of a new function: const auto& constStudentMap = studentMap; Commented May 5, 2022 at 3:57

2 Answers 2

3

No I don't think it is possible to change the type of a variable.

If you want to avoid unexpected mistake of modifying studentMap, you could pull the logic into a separate function, and refer studentMap with a const ref:

#include <iostream>
#include <string>
#include <map>

void displayStudentMap(const auto& studentMap) {
    for (const auto& [id, name] : studentMap) {
        // compilation error
        studentMap.at(id) += "test";
    }

    for (const auto& [id, name]: studentMap) {
        std::cout << id << " " << name << "\n";
    }

}

int main() {
    std::map<int, std::string> studentMap;
    studentMap[1] = "Tom";
    studentMap[7] = "Jack";
    studentMap[15] = "John";

    displayStudentMap(studentMap);
}
Sign up to request clarification or add additional context in comments.

10 Comments

thanks, can it implement using some semantics like const casting.
@amont Can you clarify, please, which semantics for example? const_cast generally is a red flag for bad design in most cases.
Beware: using auto as parameter creates a templated function. To save repeated typing an alias with using could be created instead.
On my complier, I can't transfer function parameter as auto.
C++ does not allow auto in parameter declarations -- that is provided by a non-standard compiler extension. To be compliant you want std::map<int, std::string>& studentMap You can't pass as const if you modify with += "test"; Both are easily fixed by either removing const or not modifying studentMap in the function.
|
3

This way:

const std::map<int, std::string> studentMap {
    std::make_pair(1, "Tom"),
    std::make_pair(7, "Jack"),
    std::make_pair(15, "John")
};

or this with C++11 uniform initialization:

const std::map<int, std::string> studentMap {
        { 1, "Tom" },
        { 7, "Jack" },
        { 15, "John" }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.