简体   繁体   中英

How to overload [] in vector of std::map's

I am getting these compiler errors:

1>results.cpp
1>results.cpp(28,44): error C2676: binary '[': '_Ty' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            _Ty=std::multimap<std::string,sqlite_data_type,std::less<std::string>,std::allocator<std::pair<const std::string,sqlite_data_type>>>
1>        ]
1>results.cpp(28,78): error C2676: binary '[': '_Ty' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            _Ty=std::multimap<std::string,sqlite_data_type,std::less<std::string>,std::allocator<std::pair<const std::string,sqlite_data_type>>>
1>        ]

withe the code below.

#include <vector>
#include <string>
#include <variant>
#include <iostream>
#include <map>
#include <cstdint>

using namespace std;

using sqlite_data_type = variant<int, double, string, vector<uint8_t> >;


int main() {

    multimap<string, sqlite_data_type> row1 { {"name", "Mickey Mouse"}, {"age", 12 }};
    multimap<string, sqlite_data_type> row2 { {"name", "Donald Duck"}, {"age", 23 } };

    // a tabular representation - like a collection of rows in a database
    vector<multimap<string, sqlite_data_type>> results { row1, row2 };

    cout << "row1 name: " << results[0]["name"] << ", age: " << results[0]["age"] << endl;
}

I want to be able to use the convenient results[index]["name"] syntax. how do I achieve that?

There are two fundamental problems that are preventing you from doing this.

First, a std::multimap doesn't even have an overloaded [] operator. A std::multimap , by definition, can have multiple values for the same key. Therefore, if your multimap has two values for a "name" , then which ["name"] do you want? You don't know. Neither does your multimap. Only a map has an overloaded [] operator.

Second, when all is said and done you wind up with a std::variant for a value, and there does not seem to be suitable << overload for a variant and a std::ostream . Fortunately, looks like it's easy to solve this problem, in this case. The main problem is that you cannot use a multimap:

#include <vector>
#include <string>
#include <variant>
#include <iostream>
#include <map>
#include <cstdint>
#include <functional>

using namespace std;

using sqlite_data_type = variant<int, double, string, vector<uint8_t> >;

std::ostream &operator<<(std::ostream &o, const std::vector<uint8_t> &)
{
    // You'll need to decide what you want to do here.
    return o;
}

std::ostream &operator<<(std::ostream &o, const sqlite_data_type &d)
{
    std::visit([&]
           (const auto &a)
    {
        o << a;
    }, d);

    return o;
}

int main() {

    map<string, sqlite_data_type> row1 { {"name", "Mickey Mouse"}, {"age", 12 }};
    map<string, sqlite_data_type> row2 { {"name", "Donald Duck"}, {"age", 23 } };
    
    // a tabular representation - like a collection of rows in a database
    vector<map<string, sqlite_data_type>> results { row1, row2 };

    cout << "row1 name: " << results[0]["name"] << ", age: " << results[0]["age"] << endl;
}

Note that one of the possible variant values is a vector of uint8_t , which does not have a suitable << overload either. You'll need to figure out what to do, in that case, for now I just left that as a stub.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM