如何在CRTP类层次结构中调用基类相等运算符?

时间:2018-09-23 18:10:58

标签: c++ templates crtp

我正在使用CRTP模式在类层次结构中实现相等运算符。这段代码有效,但是我需要始终在派生类的相等运算符中检查BaseClass成员的相等性,例如

 c_member == other.c_member && common_elem == other.common_elem;

如果我具有多个层次结构,则此设计会添加很多样板代码。有没有一种方法可以修改此代码,以使派生类首先检查基本部分(在此示例中为common_elem成员变量)的相等性,如果不正确,请对它们的特殊成员变量执行测试。

#include "gtest/gtest.h"
#include "gmock/gmock.h"
using namespace ::testing;    
#include <iostream>
#include <memory>    
using namespace std;    
class BaseClass
{
protected:
    int common_elem;
public:

    explicit BaseClass(int common_elem) : common_elem(common_elem) {}

    bool operator==(const BaseClass& other) const
    {
        return equals(other);
    }

    bool operator!=(const BaseClass& other) const
    {
        return (!equals(other));
    }

protected:
    virtual bool equals(const BaseClass& other) const{
        return common_elem == other.common_elem;
    }
};
template<class T>
class BaseClassCRTP : public BaseClass
{
protected:
public:
    explicit BaseClassCRTP(int common_elem) : BaseClass(common_elem) {}

protected:
    virtual  bool equals(const BaseClass& other_base)  const
    {
        const T* other = dynamic_cast<const T*>(&other_base);
        return other != nullptr && static_cast<const T&>(*this) == *other;
    }
private:
    bool operator==(const BaseClassCRTP& a) const   // force derived classes to implement their own operator==
    {
        return false;
    }
};

class B : public BaseClassCRTP<B>
{
public:
    B(int common_elem, int b_member_) : BaseClassCRTP(common_elem), b_member(b_member_) {}

    bool operator==(const B& other) const
    {
        return b_member == other.b_member  && common_elem == other.common_elem;
    }
private:
    int b_member;
};

class C : public BaseClassCRTP<C>
{
public:
    C(int common_elem, int c_member_) : BaseClassCRTP(common_elem), c_member(c_member_) {}

    bool operator==(const C& other) const
    {
        return c_member == other.c_member && common_elem == other.common_elem;
    }
private:
    int c_member;
};

TEST(Experimental, CRTP) {
    B b1(1, 1);
    B b2(1, 1);
    B b3(2, 1);
    C c1(1, 1);
    C c2(1, 1);
    EXPECT_EQ(b1, b2);
    EXPECT_NE(b1, b3);
    EXPECT_NE(b2, b3);
    EXPECT_NE(b1, c1);
    EXPECT_NE(c1, b2);
    EXPECT_EQ(c1, c2);
}

0 个答案:

没有答案