我在一个正在研究的项目中有几个班级;第一个是Solver类,最初带有一个函数模板,其完整定义在Solver头文件中,就像这样(只显示了必需品):
solver.h
class Solver {
public:
template<typename T>
void solve(T t);
}
template<typename T>
void Solver::solve(T t) {
// implementation here
}
现在,A类用作求解函数模板的模板参数,如下所示:
啊
#include "solver.h"
class A {
private:
Solver s; //s is instantiated in constructor
public:
void doSomething();
}
A.cpp
void A::doSomething() {
s.solve<A&>(*this);
}
所以现在这一切都很好,但是出于项目的目的,我需要将solve()函数模板的定义从头文件移动到实现文件(solver.cpp)中.据我所知,只要我添加明确说明将与函数模板一起使用的类型的行,我就可以这样做,如下所示:
solver.cpp
template<typename T>
void Solver::solve(T t) {
// implementation here
}
template void Solver::solve<A&>(A& a);
但是当我尝试编译求解器时这不起作用,因为为了将A指定为我想在solve.cpp中用作模板参数的类型,我需要让A不是不完整的类型.但是A要求Solver才能编译 – 所以我相信我有一个循环依赖.有什么办法可以解决这个问题吗?
我对这一切都比较陌生,所以请把它放在我身上:)非常感谢.
最佳答案 萨莫斯几乎是对的,你需要A级; (“前瞻性声明”).但只有在使用它之前,才能在Solver类之前:
编辑在回复评论时,您的最小代码示例太小了:)真正的问题是Header Guards:
#ifndef SOLVER_H_INCLUDED_
#define SOLVER_H_INCLUDED_
class Solver {
public:
template<typename T>
void solve(T t);
};
#endif // SOLVER_H_INCLUDED_
和
// A.h
#ifndef A_H_INCLUDED_
#define A_H_INCLUDED_
#include "Solver.h"
class A {
private:
Solver s; //s is instantiated in constructor
public:
void doSomething();
};
#endif // A_H_INCLUDED_
// Solver.cpp
#include "Solver.h"
#include "A.h"
template<typename T>
void Solver::solve(T t) {
// implementation here
}
// explicit instantiations
template void Solver::solve<int>(int);
// ...
template void Solver::solve<A&>(A&);
这会奏效
// main.cpp
#include "A.h"
int main()
{
A a;
a.doSomething();
}