如何转发声明类模板?

时间:2021-04-28 10:07:59

标签: c++ templates

我正在尝试实现规范模式。在那,我有一个规范抽象类和一个重载的 && 运算符,它返回 AndSpecification,它实际上是从规范类派生的。现在我有循环依赖 b/w 的问题AndSpecification 和 Specification.Specification 是一个类模板,AndSpecification 也是。

规范.h

//#include "AndSpecification.h"- this creates a problem
template <class T>
class Specification
{
 public:
     Specification()
     {

     }

     virtual ~Specification()
     {

     }
     virtual bool isSatisfied(T *item)=0;
     AndSpecification<T>  operator&&(Specification &other)
     {
         return AndSpecification<T>(*this,other);
     }
};

AndSpecification.h

#include "Specification.h"

template <class T>

class AndSpecification : public Specification<T>
{
    Specification <T> *first;
    Specification <T> *second;
public:
    AndSpecification(Specification <T> *first,Specification <T> * second);

    // Specification interface
public:
    bool isSatisfied(T *item) override;
};

将不胜感激。 完整代码:https://github.com/princekm/specification.git

3 个答案:

答案 0 :(得分:1)

您需要前向声明,并在这些类之后移动需要两个类定义的方法定义:

// Specification.h
#pragma once
template <class T> class AndSpecification;

template <class T>
class Specification
{
 public:
     Specification() {}

     virtual ~Specification() {}
     virtual bool isSatisfied(T *item)=0;
     AndSpecification<T>  operator&&(Specification &other);
};

#include "Specification.inl"
// AndSpecification.h
#pragma once

#include "Specification.h"
template <class T>
class AndSpecification : public Specification<T>
{
    Specification <T> *first;
    Specification <T> *second;
public:
    AndSpecification(Specification <T> *first,Specification <T> * second);

    // Specification interface
public:
    bool isSatisfied(T *item) override;
};
// Specification.inl
#pragma once
#include "Specification.h"
#include "AndSpecification.h"
template <class T>
AndSpecification<T>  Specification<T>::operator&&(Specification &other)
{
    return AndSpecification<T>(this, &other);
}

Demo

答案 1 :(得分:0)

转发声明:

template <class T> AndSpecification;

以下是正确的(通过删除示例中的纯虚方法):

template <class T> class AndSpecification;
template <class T>
class Specification
{
 public:
     Specification()
     {

     }

     virtual ~Specification()
     {

     }
//     virtual bool isSatisfied(T *item)=0;
     AndSpecification<T>  operator&&(Specification &other)
     {
         return AndSpecification<T>(*this,other);
     }
};
template <class T>

class AndSpecification : public Specification<T>
{
    Specification <T> *first;
    Specification <T> *second;
public:
    AndSpecification(Specification <T> *first,Specification <T> * second);

    // Specification interface
public:
    bool isSatisfied(T *item) override;
};

class A{};

int main() {
    Specification<A> a;
}

答案 2 :(得分:0)

您可以考虑 Specification 不一定需要了解 AndSpecification,而不是前向声明(请参阅其他答案)。我的意思是,无论如何它都是一个模板。如果您像这样向 Specifiacation 添加模板模板参数:

template <class T,template<typename> class X>
class Specification
{
 public:
     Specification()
     {

     }

     virtual ~Specification()
     {

     }
     virtual bool isSatisfied(T *item)=0;
     X<T>  operator&&(Specification &other)
     {
         return X<T>(*this,other);
     }
};

那么只有当你实例化它时,你才需要知道两者:

 #include "Specification.h"
 #incldue "AndSpecification.h"
 template <typename T>
 using Specification_with_And = Specification<T,AndSpecification>;
相关问题