模板化类之间的虚拟相等函数 (C++)

Virtual Equal Function between templated classes (C++)

提问人:Vero 提问时间:4/9/2022 最后编辑:Vero 更新时间:4/10/2022 访问量:82

问:

这个问题是这里的后续问题。目标是在非模板化类之间实现虚拟相等运算符。在这个问题中,我要求模板化类具有相同的目标。

#define EQUAL_FOR_BASE(derived)         virtual bool equal(const derived& eq) const { return false; };
#define EQUAL_FOR_DERIVED(this_derived) bool equal(const Equalable& equalable) const { return equalable.equal(*this_derived); };

class RandomClass; //This is for clarification purposes, not used.
class DerivedTemplateType_One;
class DerivedTemplateType_Two;

class Equalable
{
public:
    Equalable() = default;
    virtual ~Equalable() = default;
    virtual bool operator==(const Equalable& eq) { return this->equal(eq); };
    EQUAL_FOR_BASE(RandomClass);
    EQUAL_FOR_BASE(DerivedTemplateType_One);
    EQUAL_FOR_BASE(DerivedTemplateType_Two);
    virtual bool equal(const Equalable& eq) const = 0;
};

class RandomClass : public Equalable
{
public:
    RandomClass() = default;
    ~RandomClass() = default;
    EQUAL_FOR_DERIVED(this);
    virtual bool equal(const RandomClass& rc) const { return m_double == rc.m_double; };
    double m_double;
};

class TemplateType : public Equalable //Still pure virtual due to equal in Equalable.
{
public:
    TemplateType() = default;
    virtual ~TemplateType() = default;
    int m_string;
};


class DerivedTemplateType_One : public TemplateType
{
public:
    EQUAL_FOR_DERIVED(this);
    virtual bool equal(const DerivedTemplateType_One& one) const { return m_int == one.m_int; };
    int m_int;
};

class DerivedTemplateType_Two : public TemplateType
{
public:
    EQUAL_FOR_DERIVED(this);
    virtual bool equal(const DerivedTemplateType_Two& two) const { return m_size == two.m_size; };
    std::size_t m_size;
};

template<typename T>
class Target : Equalable
{
public:
    T m_t;
};

Q1:我想将上面的模板类型名称 T 限制为 TemplateType 的派生类(派生自 Equalable),例如可以是 DerivedTemplateType_One/Two(当然会有 Three、Four..)?在编译时没有static_assert或一些元编程来检查这一点,或者会:

template<TemplateType DerivedTypeOneOrTwo>
class Target : public Equalable
{
public:
    DerivedTypeOneOrTwo m_t;
};

工作?

Q2:我怎样才能像对 RandomClass 所做的那样实现相等运算符?

Q3:我问 Q1 是为了限制可能的模板类型,以便 Q2 成为可能,我可以将 Q1:将模板类型名称 T 限制为继承自 Equalable(而不是 TemplateType)的类,并且仍然执行 Q2 吗?

对不起,这有点复杂,但没有简单的方法可以:)非常感谢!!

Ps:为了节省空间,我把所有内容都公开了,请忽略。

C++ 模板 运算符重载 虚拟 相等

评论

0赞 Vero 4/10/2022
我可以在这里使用boost吗:链接

答:

0赞 Vero 4/10/2022 #1

如果有人有兴趣,我结束了使用 CRTP(如果我做错了我错过了什么,请告诉我)

template<class Derived>
class Equalable
{
public:
    using derived_type = Derived;
    bool operator==(const Derived& derived) const { return this->equal(derived); };
    bool operator!=(const Derived& derived) const { return !(*this == derived); }
    
private:
    virtual bool equal(const Derived& derived) const = 0;
};

class B : public Equalable<B>
{
public:
    B(double d) : m_example(d) {};
private:
    virtual bool equal(const B& derived) const override { return derived.m_example == m_example; };
    double m_example;
};

class A : public Equalable<A>
{
public:
    A(std::string d) : m_example(d) {};
private:
    virtual bool equal(const A& derived) const override { return derived.m_example == m_example; };
    std::string m_example;
};

现在我们可以比较相同类型的元素:

int main()
{
    A a("string");
    B b(1);
    A aa("other_string");
    B bb(11);
    std::cout << (a == aa) << std::endl; //Ok
    std::cout << (b == bb) << std::endl; //Ok
    std::cout << (a == b) << std::endl;  //Wrong, not supported.
};

我试着这样做:

template<class A, class B>
static bool equal(const Equalable<A>& a, const Equalable<B>& b)
{
    if (!std::is_same<A, B>::value)
        return false;
    return a == b;
};

但是没有编译,所以我只是使用了相同类型之间的相等性。

要限制模板(截至问题 Q1),有一个标准检查:

static_assert(std::is_base_of<Base, Derived>::value, "Only from Base");

希望你有更好的建议,我还是不喜欢这个:)谢谢大家!

评论

1赞 apple apple 4/10/2022
关于比较的问题可能不是与基本参考不同的类型吗?你不需要这个复合体来定义它,只需与类型本身进行比较。operator==
0赞 Vero 4/10/2022
是的。是的。但找不到解决方案!所以我刚刚破解了这个,请帮助任何对第一个问题有更好答案的人!