开发者

C++ templated map contain itself

开发者 https://www.devze.com 2023-03-26 17:22 出处:网络
I have a templated class, that can have a map type as template parameter. template<typename map_t> class my_开发者_Go百科class

I have a templated class, that can have a map type as template parameter.

template<typename map_t> class my_开发者_Go百科class
{
    map_t my_map;
};

Now I'd like the value type of the map, to be equal to this class.

my_class<std::map<std::string, my_class<...> > > problems;

However, this is impossible to declare. How can I achieve the same effect?


Since you want to be generic in the container type, the closest I have been able to find (if I understand well your intent) is:

template <template <typename, typename> class Map>
struct my_class
{
    typedef typename Map<std::string, my_class>::type map_t;
    map_t children;
};

// Since the standard doesn't allow default arguments to be
// taken into account for template template parameters, we
// have to close them.
// Write one such structure for each map type you want.
struct std_map
{ 
    template <typename Key, typename Value>
    struct rebind { typedef std::map<Key, Value> type; }
};

and use

my_class<std_map::rebind> problematic_tree;


Have you tried this

template<typename T> class my_class
{

    std::map< std::string , my_class> my_map;
};

It might be better if you don't pass the map as a template parameter and instead pass map key , value and comparison operator as template parameters


You can't do that, because it's infinitely recursive. You can do either a fixed depth, or you will have to use some dynamic determination of the values within via inheritance, a Variant, or something like that.


You can't do that. The nearest thing you can do is Curiously recurring template pattern.


It seems like you should be able to forward declare my_class<T> and use a pointer to that as your mapped_type (in C++ value_type means a pair including both the key and value for maps).


As others pointed out you cannot create an infinitely recursive class definition, but you can certainly nest my_class a finite number of times. Here's a working example:

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

template<typename map_t> struct my_class {
    map_t my_map;
};

my_class<std::map<std::string, my_class<std::map<std::string, int> > > > problems;

int main() {
    std::cout << problems.my_map.size();
    return 0;
}


The class can't actually contain itself as a member (think how much memory you'd need to contain it), but it can contain a pointer to itself. You can implement this using the pattern J-16 SDiZ cited, or some bait-and-switch:

template<typename map_t> class my_class
{
  map_t * my_map;
};

class dummy;
template<>
class my_class<dummy>
{
  my_class<dummy> * my_map;
};
0

精彩评论

暂无评论...
验证码 换一张
取 消