2011-08-07 27 views
3

我有一个模板类,可以有一个地图类型作为模板参数。C++模板地图本身包含

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

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

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

但是,这是不可能申报的。我怎样才能达到同样的效果?

+1

好的。但为什么你需要这样的事情? – Ajay

+0

我需要这个来实现一个灵活的序列化解决方案。 – Ruud

回答

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; 
+0

非常感谢,这是我寻找的解决方案! – Ruud

+1

我仍然想知道,这个解决方案是如何工作的?你能解释为什么这个工作? – Ruud

1

你有没有试过这种

template<typename T> class my_class 
{ 

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

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

+0

我需要能够将容器作为模板参数传递,以便能够使用不同的容器。这允许为特定情况优化容器。 – Ruud

0

似乎就像你应该能够转发声明my_class<T>并使用指针作为你的mapped_type(在C++ value_type意味着一对包括映射的键和值)。

1

你不能这样做,因为它是无限递归的。你可以做一个固定的深度,或者你将不得不使用通过继承,变体或类似的东西来动态确定值。

+0

这是不正确的。我可以用一个硬编码的std :: map替换模板化的map_t,这样可以正常工作。 – Ruud

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

类实际上并不能包含本身成为会员(觉得你需要多少内存来容纳它),但是它可以包含一个POIN本身就是。你可以使用引用的模式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; 
};