如何在 std::map 的向量中重载 []

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

我遇到了这些编译器错误:

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>        ]

使用下面的代码。

#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;
}

我希望能够使用方便的 results[index]["name"] 语法。我该如何实现?

有两个基本问题阻止您这样做。

首先,std::multimap 甚至没有重载的 [] 运算符。 std::multimap,根据定义,同一个键可以有多个值。因此,如果您的 multimap 有两个 "name" 值,那么您想要哪个 ["name"]?你不知道。你的多图也没有。只有 map 具有重载的 [] 运算符。

其次,总而言之,您最终得到了一个 std::variant 作为值,并且似乎没有合适的 << 重载变体和 std::ostream.幸运的是,在这种情况下,看起来很容易解决这个问题。主要问题是你不能使用多图:

#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;
}

请注意,可能的变体值之一是 uint8_t 的向量,它也没有合适的 << 重载。在这种情况下,您需要弄清楚该怎么做,现在我只是将其保留为存根。