Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shorthand syntax for c++ map in map

Tags:

c++

map

If I have definitions like:

typedef map<string, Foo> Foo_map_1
typedef map<string, Foo_map_1> Foo_map_2
typedef map<string, Foo_map_2> Foo_map_3
typedef map<string, Foo_map_3> Foo_map_4
typedef map<string, Foo_map_4> Foo_map_5

Is there anyway I can generalize that so I could do, for example,

Foo_map<10>

and have a 10-fold nested map. I don't need something like boost::recursive_wrapper because the number of levels is always constant.

like image 757
mikesol Avatar asked May 12 '14 05:05

mikesol


People also ask

What is map C?

​Maps are a part of the C++ STL. Maps are associative containers that store elements in a combination of key values and mapped values that follow a specific order. No two mapped values can have the same key values. In C++, maps store the key values in ascending order by default.

Are maps ordered C++?

By default, a Map in C++ is sorted in increasing order based on its key.

How do you define a map in C++?

A map can be declared as follows: #include <iostream> #include <map> map<int, int> sample_map; Each map entry consists of a pair: a key and a value. In this case, both the key and the value are defined as integers, but you can use other types as well: strings, vectors, types you define yourself, and more.

How do you check if a value is in a map C++?

To check for the existence of a particular key in the map, the standard solution is to use the public member function find() of the ordered or the unordered map container, which returns an iterator to the key-value pair if the specified key is found, or iterator to the end of the container if the specified key is not ...


2 Answers

This is seems easy enough even for the limited C++ metaprogramming power:

#include <map>
#include <string>

template<int N, typename K, typename V>
struct NMap { typedef std::map<K, typename NMap<N-1, K, V>::type> type; };

template<typename K, typename V>
struct NMap<1, K, V> { typedef std::map<K, V> type; };

int main(int argc, const char *argv[]) {
    NMap<3, int, std::string>::type m;
    m[1][2][3] = "Test";
    return 0;
}
like image 195
6502 Avatar answered Sep 24 '22 06:09

6502


This works for me.

#include <iostream>
#include <string>
#include <map>
using namespace std;

struct Foo
{
   Foo() : _in(0) {}
   Foo(int in) : _in(in) {}
   int _in;
};

template <int N> struct Foo_map
{
   map<string, Foo_map<N-1> > foo_Map;
   Foo_map<N-1>& operator[](string const& key) { return foo_Map[key]; }
};

template <> struct Foo_map<1>
{
   map<string, Foo> foo_Map;
   Foo& operator[](string const& key) { return foo_Map[key]; }
};

int main()
{
   Foo_map<1> map1;
   map1["abcd"] = Foo(10);

   Foo_map<2> map2;
   map2["a"]["b"] = Foo(20);

   Foo_map<10> map10;
   map10["a"]["b"]["c"]["d"]["e"]["f"]["g"]["h"]["i"]["j"] = Foo(100);

   std::cout << map1["abcd"]._in << std::endl;
   std::cout << map2["a"]["b"]._in << std::endl;
   std::cout << map10["a"]["b"]["c"]["d"]["e"]["f"]["g"]["h"]["i"]["j"]._in << std::endl;
}

The output of running the program:

10
20
100
like image 24
R Sahu Avatar answered Sep 22 '22 06:09

R Sahu