我有一个名为Temp的模板类,它有一个采用相同类型参数的方法:
#ifndef TEMP_H
#define TEMP_H
template<class T>
class Temp
{
public:
T data;
bool comp(T);
};
template<class T>
bool Temp<T>::comp(T data)
{
return (this -> data < data);
}
#endif // TEMP_H
现在,我想创建一个Temp类的对象,该对象的指针类型指向另一个名为Foo的类。
Temp<Foo*> TptrF;
通常这很容易,对于方法comp
,我可以对此特定类型Foo*
进行特殊化,但是我必须在Foo.h
中包含文件Temp.h
:
//Temp.h
#ifndef TEMP_H
#define TEMP_H
#include "Foo.h"
template<class T>
class Temp
{
public:
T data;
bool comp(T);
};
template<class T>
bool Temp<T>::comp(T data)
{
return (this -> data < data);
}
template<>
inline bool Temp<Foo*>::comp(Foo* data)
{
return (this -> data -> val < data -> val);
}
#endif // TEMP_H
但是问题是Foo类的对象类型为Temp<int>
,对于Foo中的此数据成员,我必须在Temp.h
中包含文件Foo.h
:
//Foo.h
#ifndef FOO_H
#define FOO_H
#include "Temp.h"
class Foo
{
public:
int val;
Temp<int> Ti;
};
#endif // FOO_H
这给了我Foo.h
:
错误:“临时”未命名类型
我试图从#include "Foo.h"
中删除Temp.h
并使用class Foo;
之类的前向声明,但是由于我使用了Foo类中的'val'数据成员,所以它不起作用comp
函数,它在Temp.h
中给了我:
错误:无效使用了不完整的“ Foo类”
并尝试从#include "Temp.h"
中删除Foo.h
,并使用像template<class T> class Temp;
这样的前向模板声明,我认为这会起作用,因为我只需要一个对象,所以我只想要编译器知道我有一个名为Temp的模板类,但它也没有用,它在Foo.h
中给出了我的名字:
错误:字段“ Ti”的类型不完整
Temp<int>
我应该怎么做才能使此代码起作用?
Temp<int>
和Temp<Foo*>
彼此不包含为对象,因此我认为这应该在逻辑上起作用,或者仅仅是不良设计的后果之一。
答案 0 :(得分:1)
摆脱comp
的声明Foo
,该声明在Temp.h
中的类型为operator<
,而在Foo
中的重载class Foo
{
public:
int val;
Temp<int> Ti;
bool operator<(const Foo& f) {
return val < f.val;
}
};
:
FooDataTemplate
我只是在输入它,所以希望它可以编译。
答案 1 :(得分:1)
这需要知道Foo
是什么data->val
的编译。因此,只需将其移至Foo.h
class Foo {
...
};
template<>
inline bool Temp<Foo*>::comp(Foo* data)
{
return (this -> data -> val < data -> val);
}