简体   繁体   English

用 std::tuple 实现多维 std::map 和视图访问

[英]Implement multi-dimensional std::map with std::tuple and view access

I know that I can create a multi-dimensional map by nesting maps together, eg:我知道我可以通过将地图嵌套在一起来创建多维 map,例如:

// Two-dimensional key
map<string, map<int, double> > m;

so it is easy to extract all of the values associated to the highest order key.因此很容易提取与最高阶键关联的所有值。 So if I have a set of data that looks like this:因此,如果我有一组如下所示的数据:

A1 : 23.0
A2 : 45.3
A5 : 5.88
B9 : 7.2
B10 : 79.74

I could store it as std::map<std::string, std::map<uint, float>> mymap and easily retrieve all of the A values by doing mymap["A"] .我可以将其存储为std::map<std::string, std::map<uint, float>> mymap并通过执行mymap["A"]轻松检索所有A值。

I also know I can create a std::map with multiple keys by using a std::tuple , which is more intuitive: std::map<std::tuple<std::string,uint>, float> mymap我也知道我可以使用std::tuple创建一个带有多个键的std::map ,这更直观: std::map<std::tuple<std::string,uint>, float> mymap

but is there a c++14 way to get all of the A elements with this second implementation?但是是否有一种c++14方法可以通过第二种实现方式获取所有A元素?

std::map<std::tuple<std::string,uint>, float> mymap

I'm assuming uint means unsigned int .我假设uint意味着unsigned int

For this particular case, map::lower_bound and map::upper_bound may be combined:对于这种特殊情况, map::lower_boundmap::upper_bound可以组合:

auto beg = mymap.lower_bound({"A",0});
auto end = mymap.upper_bound({"A", static_cast<unsigned>(-1)});

for(auto it = beg; it != end; ++it) {
    std::cout << it->second << '\n'; // only "A" records
}
  • lower_bound will return an iterator to the first element not less than the given key, which is the first possible valid A entry, {"A", 0} . lower_bound将返回一个迭代器,指向不小于给定键的第一个元素,这是第一个可能的有效A条目{"A", 0}

  • upper_bound will return an iterator to the first element greater than the given key, which is the last possible valid A entry, {"A", (unsigned) -1} . upper_bound将返回一个迭代器,指向大于给定键的第一个元素,这是最后一个可能的有效A条目{"A", (unsigned) -1}

You can use std::map::equal_range .您可以使用std::map::equal_range It requires you to provide a transparent comparator, which is easy to make:它要求您提供一个透明的比较器,它很容易制作:

#include <cstdio>
#include <map>
#include <string>
#include <utility>

using Key = std::pair<std::string, int>;

struct Cmp {
    bool operator()(Key const& e1, std::string const& e2) const noexcept {
        return e1.first < e2;
    }

    bool operator()(std::string const& e1, Key const& e2) const noexcept {
        return e1 < e2.first;
    }

    bool operator()(Key const& e1, Key const& e2) const noexcept {
        return e1 < e2;
    }

    using is_transparent = bool;
};

int main() {
    std::map<Key, float, Cmp> map;

    map.insert({{"A", 1}, 23.0F});
    map.insert({{"A", 2}, 45.3F});
    map.insert({{"A", 5}, 5.88F});
    map.insert({{"B", 9}, 7.20F});
    map.insert({{"B", 10}, 79.74F});

    auto const rng = map.equal_range("A");
    for (auto it = rng.first; it != rng.second; ++it) {
        std::printf("%s%d : %.2f\n", 
                    it->first.first.c_str(), 
                    it->first.second,
                    it->second);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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