文件ex1.hpp(模板类的定义):
#ifndef EX1_HPP
#define EX1_HPP
#include "ex2.hpp"
template <class T>
class Ex1{
public:
void Ex1method(){
Ex2 a; // using nontemplate class object
a.Ex2method();
}
};
#endif
文件ex2.hpp(nontemplate类的定义):
#ifndef EX2_HPP
#define EX2_HPP
#include "ex1.hpp"
class Ex2{
public:
void Ex2method();
};
#endif
文件ex2.cpp(nontemplate类方法的定义):
#include "ex2.hpp"
void Ex2::Ex2method()
{
Ex1<int> e; // using template class object
e.Ex1method();
}
编译错误:
ex1.hpp:10:9: error: ‘Ex2’ was not declared in this scope
ex1.hpp:10:13: error: expected ‘;’ before ‘a’
ex1.hpp:11:9: error: ‘a’ was not declared in this scope
如何解决nontemplate类和模板类之间的这种循环依赖关系?我无法将nontemplate类方法定义为实现文件,因为它会导致链接器错误。如果我在文件ex1.hpp中放置Ex2类的声明,那么错误是:
error: invalid use of incomplete type ‘struct Ex2’
error: forward declaration of ‘struct Ex2’
答案 0 :(得分:3)
请勿在{{1}}中加入ex1.hpp
,因此没有必要。您的标题没有循环依赖。
在ex2.hpp
文件中包含两个标题(或只是ex1.hpp
),一切都应该是好的。
答案 1 :(得分:1)
从ex2.h,移动
#include "ex1.hpp"
到ex2.cpp
答案 2 :(得分:1)
根本不需要ex1.hpp
ex2.hpp
。从ex2.cpp
包含它,而循环依赖将会消失。
答案 3 :(得分:1)
如果Ext1
中确实需要Ext2
,例如Ext1
中有Ext2
成员,您仍然可以使用Ext2
取决于T
。然后,当实际调用模板的成员函数时,您只需要Ext2
的完整定义。
class Ext2;
template <class T, class>
class Identity {
typedef T type;
};
template <class T>
class Ex1{
public:
void Ex1method(){
typename Identity<Ex2, T>::type a;
a.Ex2method();
}
};
现在,如果Ext1method
的用户希望调用该成员函数,则可以包含Ext2
的标头。现在不再需要在Ext2.hpp
中添加Ext1.hpp
了。但是这种并发症只有在
Ext1.hpp
或Ext2.pph
Ext1method
的用户自动包含Ext2.h
(“名称污染”)。