Как вызвать оператор равенства базового класса в иерархии классов CRTP? - PullRequest
0 голосов
/ 23 сентября 2018

Я использую шаблон 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);
}
...