带变体的无限嵌套地图

时间:2018-10-19 12:33:48

标签: c++ c++17

因此,我正在尝试制作可无限嵌套的地图,并且可以在其中使用字符串,整数,布尔值等。

这是我尝试过的:

        <tbody data-bind="foreach: customers">
        <tr>
            <td><input type="text" class="form-control" size="5" data-bind="value: CustomerID" /></td>
            <td><input type="text" class="form-control" data-bind="value: CompanyName" /></td>
            <td><input type="text" class="form-control" data-bind="value: ContactName" /></td>
            <td><input type="text" class="form-control" data-bind="value: Country" /></td>
            <td>
                <input type="button" class="form-control" value="Insert" data-bind='click: $root.AddCustomer' />
                <input type="button" class="form-control" value="Delete" data-bind='click: $root.DeleteCustomer' />
            </td>
        </tr>
    </tbody>

这是合乎逻辑的,struct NMap; struct NMap : std::map<std::string, std::variant<NMAP*, std::string, std::any>> {}; // ... NMap* something; something["lorem"]["ipsum"] = "Test"; ^ - No such operator [] 没有std::variant运算符。无论如何,可嵌套地图中是否使用[]

3 个答案:

答案 0 :(得分:6)

简单又怪异的东西

#include <map>
#include <string>
#include <optional>

struct rmap : std::map<std::string, rmap>
{
    std::optional<std::string> value; // could be anything (std::variant, std::any, ...)
};

稍加糖和其他一些雅致的调整,就可以像打算那样使用它:

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

struct rmap : std::map<std::string, rmap>
{
    using value_type = std::optional<std::string>;
    value_type value;
    operator const value_type&() const { return value; }
    rmap& operator=(value_type&& v) { value = v; return *this; }
    friend std::ostream& operator<<(std::ostream& os, rmap& m) { return os << (m.value ? *m.value : "(nil)"); }
};

int main()
{
    rmap m;
    m["hello"]["world"] = std::nullopt;
    m["vive"]["le"]["cassoulet"] = "Obama";

    std::cout << m["does not exist"]  << '\n';          // nil
    std::cout << m["hello"]["world"]  << '\n';          // nil
    std::cout << m["vive"]["le"]["cassoulet"]  << '\n'; // Obama
}

您可以使用一些语法糖来调整自己的口味。

答案 1 :(得分:0)

我想它一定是这样的:

(*std::get<NMap *>(something["lorem"]))["ipsum"] = "Test";

答案 2 :(得分:0)

std :: variant不支持递归使用,请参见此long answer。注意:这不是一个适合初学者的主题。