如何声明引用自身的模板化类型?
template <class T = Animal> class Animal
{
public:
T getChild ();
}
有了这个,我得到一个关于缺少类型说明符的编译器错误。我试图转发声明Animal
,但没有成功。
我试图强加一个类型约束。 Lion
作为孩子只能有Lion
,Bear
有Bear
,依此类推。
修改
我将发布部分实际课程。它是可以出现在链表中的类的模板:
template <class T = Linked<T> > class Linked
{
private:
T* m_prev;
T* m_next;
}
我想强制该类只能指向同一个类(或子类)的对象。
答案 0 :(得分:4)
在这种情况下,您需要在typename定义中为Animal指定一些类型参数,否则它将是类型构造中的“无限递归”:
template<class T> class Animal;//you'll need this forward declaration
template <class T = Animal<int> > class Animal //int is just an example
{
public:
T getPrey ();
}
答案 1 :(得分:4)
OP已被回答,但我想插话,因为问题的直接原因不是递归,正如其他人所说的那样。这不起作用的最简单的原因是类模板是不是类型。它们是模板。同样,功能模板也不是功能。所以这一切都是荒谬的:
template<typename T> int function_template(int);
typedef int function_type(int);
void eats_a_function(function_type&); // needs a reference to function
std::vector< std::vector > vec0; // std::vector is not a type
std::vector< std::list > vec1; // std::list is not a type
eats_a_function(function_template); // function_template is not a function
请注意,在vec1
案例中,std::list
与std::vector
无关。在实例化时完全定义模板(假设包含头)。它仍然无法运作。
相反,以下工作:
std::vector< std::vector<int> > vec2; // std::vector<int> is a type
std::vector< std::list<double> > vec3; // std::list<double> is a type
eats_a_function(function_template<long>); // function_template<long> is a function
请注意,在vec2的情况下,可以传递模板本身的实例化。
为了记录,玩具解决了玩具问题,写了一个引用自己的模板,使用间接的谚语层:
// expects a template that expects a type
template<template<class> class T> struct indirection {};
// forward decl. for defaulting the parameter
template<typename T> struct recursive;
// template that expects a type
template<typename T = indirection<recursive> > struct recursive {};
考虑到模板可能存在的一些事情(T
内的indirection
参数),这不是非常强大。当然可以编写一个rebind
样式的元函数来返回T
的实例化。
答案 2 :(得分:1)
您无法创建模板类,其中模板类型是类本身。这是编译器无法缓解的逻辑递归。由于模板需要编译器在遇到特定类型时构造对象(比如Animal),因此您必须具有模板类型的完整定义。否则,编译器将递归尝试构造对象。由于您的对象是自引用的,因此这将是一个非终止递归。
这个用例似乎更适合继承而不是模板。
这样做可以让你编译: 模板类动物 { 上市: T getPrey(); }
或者,如果你真的不是默认参数:
template <class T=Cheetah> class Animal
{
public:
T getPrey ();
}
然而,猎豹绝不能将自己或动物作为其潜在的模板类型之一。
答案 3 :(得分:1)
执行类似链接列表的常用方法是:
template <class T> class Linked
{
private:
Linked<T>* m_prev;
Linked<T>* m_next;
}
这对你有用吗,如果没有,你想要完成的是不能用这种方式完成的?