2013-07-30 62 views
6

有什么办法可以获得递归模板类型吗?我有一个容器,我想指定一个底层存储策略。内部模板必须使用外部模板的类型,所以它会在类型定义中产生一个循环 - 这是无法指定的。容器/类型名转发的递归模板类型

关于我想要的东西:

template<typename C> 
struct inner { 
    C * object[16]; 
}; 

template<typename T, typename Inner> 
struct container { 
    T value; 
    Inner<container> holder; 
}; 

C++ 11的解决方案是罚款(虽然我仍然在GCC 4.6.3)。

+3

有一种叫做“好奇递归模板模式”(CRTP)的东西?也许它会帮助,不确定... http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – Jimbo

+0

这种递归数据类型将有哪些新行为将它与链接列表区分开来? – abiessu

+0

@abiessu,我目前的用途实际上是基数树。每个节点都有一个如何到达下一个节点的索引,“内部”是指定该索引的策略。也就是说,模板允许说明孩子是如何管理的,而不是固定的红黑,散列或其他策略。 –

回答

5

你需要告诉编译器Inner是一个模板类:

template<typename T, template<typename> class Inner> 
struct container { 
    T value; 
    Inner<container> holder; 
}; 
+0

为什么它必须是Inner之前的'class'?我明白这不是一个通用的参数了,而是一个类的类型,尽管我期望'struct'也可以工作。因为它不,我不确定我是否理解。 –

+0

@ edA-qamort-ora-y模板是如何工作的。您可以使用通用的'typename'关键字或'class'。然而,在这种情况下,因为'Inner'本身就是一个模板类,所以它必须被声明为模板'class'。您可以定义模板化结构,但不能在模板参数列表中定义。 –

0

我不知道为什么你要添加的Inner类型模板参数,因为你定义holder是一种类型的基于Containerinner,这两者都可以在您声明持有者的地方提供。

您打算使用struct inner以外的任何其他类型作为模板参数吗?Container?如果没有,下面的简化代码编译和VS2010跑了我:

#include <vector> 
#include <stdio.h> 

template <typename C> 
struct inner{ 
    C * objects[16]; 
    bool hasobj; 

    inner():hasobj(false){} 
}; 

template <typename T> 
class Container { 
    inner<Container> holder; 
    T value; 
public: 

    Container(const T& valueP){ 
     value = valueP; 
    } 
    void AddChild(Container* rhs){ 
     holder.objects[0] = rhs; //Always using first location, just for example 
     holder.hasobj = true; 
    } 

    void PrintStuff()const{ 
     if(holder.hasobj){ 
      holder.objects[0]->PrintStuff(); 
     } 
     printf("VAL IS %d\n", value); 
    } 
}; 

int main(){ 
    Container<int> c(10); 

    Container<int> c1(20); 
    c1.AddChild(&c); 
    c1.PrintStuff(); 
} 

基本上,这是假设container总是在inner来定义holder,这有助于摆脱多余的模板参数,当定义Container。希望这有助于:) 阿伦

+0

关于Inner,是的,那是目的,你可以选择用于内部类的类型。 –