C函数模板的循环依赖问题

我在一个正在研究的项目中有几个班级;第一个是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();
}
点赞