C ++模板映射包含自身

时间:2011-08-07 14:39:52

标签: c++ templates recursion stdmap

我有一个模板化的类,可以将地图类型作为模板参数。

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

现在我想要地图的值类型,等于这个类。

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

然而,这是不可能宣布的。我怎样才能达到同样的效果?

7 个答案:

答案 0 :(得分:1)

你试过这个吗?

template<typename T> class my_class
{

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

如果不将地图作为模板参数传递,而是将地图键,值和比较运算符作为模板参数传递,则可能会更好

答案 1 :(得分:1)

你不能这样做,因为它是无限递归的。你可以做一个固定的深度,或者你必须使用一些动态确定via继承,Variant或类似的值。

答案 2 :(得分:1)

由于你想在容器类型中是通用的,我能找到的最接近的(如果我理解你的意图)是:

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

并使用

my_class<std_map::rebind> problematic_tree;

答案 3 :(得分:0)

你做不到。 你可以做的最近的事情是Curiously recurring template pattern

答案 4 :(得分:0)

您似乎应该能够转发声明my_class<T>并使用指向该mapped_type的指针(在C ++中value_type表示包含地图的键和值的一对)。

答案 5 :(得分:0)

正如其他人指出的那样,你不能创建一个无限递归的类定义,但你肯定可以有限次地嵌套my_class。这是一个有效的例子:

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

答案 6 :(得分:0)

该类实际上不能包含本身作为成员(想想你需要包含多少内存),但它可以包含一个指针到它自己。您可以使用引用的J-16 SDiZ模式或一些诱饵和开关来实现这一点:

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

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