1 year ago

#329968

test-img

Huy Le

C++ const-reference loop over a vector containing map

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <any>
using namespace std;

using MapAny = std::unordered_map<string, std::any>;


int main()
{
    vector<MapAny> params;
    params.push_back({ {"a", 1}, {"b", 2} });
    params.push_back({ {"a", 4}, {"b", 6} });
    params.push_back({ {"a", 10}, {"b", 15} });

    // I want to const-reference loop over params
    for (int i=0; i<params.size(); i++) {
        auto param = params[i]; // slow copy, not refernece 
        //auto& param = params[i]; // work but I want const
        //const auto& param = params[i]; // compile error        

        cout << any_cast<int>(param["a"]) << " " << any_cast<int>(param["b"]) << "\n";
    }
    
    // doesn't compile
    for (const auto& param : params) {
        //cout << any_cast<int>(param["a"]) << " " << any_cast<int>(param["b"]) << "\n";
    }

    // also doesn't compile
    for (auto it=params.cbegin(); it!=params.cend(); it++) {
        //cout << any_cast<int>((*it)["a"])) << " " << any_cast<int>(param["b"]) << "\n";
    }

    return 0;
}

I have a vector containing map objects. I wish to loop over each map as const reference. However, using const auto& doesn't work and it gives error at the [] operator.

How can I fix the above code to loop the vector by const-reference ?

Edit: the compiler error if I use const auto& param = params[i] is:

test_auto.cpp: In function ‘int main()’:
test_auto.cpp:25:40: error: passing ‘const std::unordered_map<std::__cxx11::basic_string<char>, std::any>’ as ‘this’ argument discards qualifiers [-fpermissive]
   25 |         cout << any_cast<int>(param["a"]) << " " << any_cast<int>(param["b"]) << "\n";
      |                                        ^
In file included from /usr/include/c++/10/unordered_map:47,
                 from test_auto.cpp:5:
/usr/include/c++/10/bits/unordered_map.h:987:7: note:   in call to ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = std::any; _Hash = std::hash<std::__cxx11::basic_string<char> >; _Pred = std::equal_to<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::any> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = std::any; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = std::__cxx11::basic_string<char>]’
  987 |       operator[](key_type&& __k)
      |       ^~~~~~~~
test_auto.cpp:25:76: error: passing ‘const std::unordered_map<std::__cxx11::basic_string<char>, std::any>’ as ‘this’ argument discards qualifiers [-fpermissive]
   25 |         cout << any_cast<int>(param["a"]) << " " << any_cast<int>(param["b"]) << "\n";
      |                                                                            ^
In file included from /usr/include/c++/10/unordered_map:47,
                 from test_auto.cpp:5:
/usr/include/c++/10/bits/unordered_map.h:987:7: note:   in call to ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = std::any; _Hash = std::hash<std::__cxx11::basic_string<char> >; _Pred = std::equal_to<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::any> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = std::any; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = std::__cxx11::basic_string<char>]’
  987 |       operator[](key_type&& __k)
      |       ^~~~~~~~

c++

vector

reference

auto

const-reference

0 Answers

Your Answer

Accepted video resources