4

我正在从事的项目中有几个课程;第一个是 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);
}

所以这一切都很好,就像现在一样,但为了项目的目的,我需要将solver()函数模板的定义从头文件中移动到一个实现文件(solver.cpp)中。据我了解,只要我添加明确说明函数模板将使用哪些类型的行,我就可以做到这一点,如下所示:

求解器.cpp

template<typename T>
void Solver::solve(T t) {
  // implementation here
}

template void Solver::solve<A&>(A& a);

但是,当我尝试编译求解器时,这不起作用,因为为了将 A 指定为我想在 solve.cpp 中用作模板参数的类型,我需要 A 不是不完整的类型。但是 A 需要 Solver 才能编译 - 所以我相信我有一个循环依赖。有什么办法可以解决这个问题吗?

我对这一切都比较陌生,所以请放轻松:) 非常感谢。

4

3 回答 3

2

Samoth 几乎是对的,你需要class 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();
}
于 2013-07-05T06:51:15.110 回答
0

你可以做的是:

求解器.h

   #ifndef SOLVER_H_INCLUDED_
   #define SOLVER_H_INCLUDED_
    class Solver {
    public:
      template<typename T>
      void solve(T t);

    };
    #include "solver.cpp"
    #endif

求解器.cpp

#include "solver.h"

template<typename T>
void Solver::solve(T t) {
  // implementation here
}

和 a.hpp

    #ifndef A_H_INCLUDED_
    #define A_H_INCLUDED_
    #include "solver.h"
    class A {
    private:
      Solver s;  //s is instantiated in constructor

    public:
      void doSomething()
      {
        s.solve(*this);
      }
    };
   #endif
于 2013-07-05T06:45:00.103 回答
0

传递循环依赖的最佳方法是这样做:

class A; // before the class Solver

class Solver {
  public:
    template<typename T>
    void solve(T t);
}

template<typename T>
void Solver::solve(T t) {
  // implementation here
}
于 2013-07-05T06:36:09.900 回答