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

发布于 01-20 01:14 字数 2466 浏览 4 评论 0原文

这个问题是在这里。目标是在非模板类别之间实现虚拟平等运算符。在这个问题中,我要求为模板班的目标提供相同的目标。

#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 :我想将上面的模板打字限制为派生的TemplateType类(源自均衡)类别的类别,例如可以派生teriveTemplateTeTepe_One/二(当然会有三个,四个..)?是否存在static_assert或某些元编程来在编译时间检查此问题,还是可以:

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

工作?

Q2 :我该如何像我为RandomClass一样实现平等运算符?

Q3 :我正在询问Q1,以限制可能的模板类型,以便Q2可以概括Q1:限制模板typname t typeName t tote of qualiealable(而不是TemplateType),并且仍然可以做Q2 ?

抱歉,这有点复杂,但是没有简单的方法:)非常感谢!

PS:我正在公开一切以节省空间,请忽略。

This question is a follow up on Here. The goal was to implement a virtual equal operator between non templated classes. In this question, I am asking for the same goal for a templated class.

#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: I want to limit the template typename T above to be a derived class of TemplateType (derived from Equalable) e.g. Can be DerivedTemplateType_One/Two (Of course there will be Three, Four..)? Isn't there static_assert or some metaprogramming to check this at compile time or would:

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

Work?

Q2: How can I implement the equal operator as I did for RandomClass please?

Q3: I am asking about Q1 in order to limit template types possible so that Q2 is possible, can I generalize Q1: Limit template typename T to classes inheriting from Equalable (instead of TemplateType ) and still do Q2?

Sorry this is getting a bit complicated but there is no easy way :) Thanks very much!!

Ps: I am making everything public to save space, please ignore.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悸初2025-01-27 01:14:53

如果有人有兴趣,我结束了使用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");

希望您有更好的建议,我仍然不喜欢这个:)谢谢大家!

I ended using CRTP if anyone is interested (Please let me know if I am doing something wrong I missed)

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;
};

Now we can compare element of same type:

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.
};

I tried doing this:

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;
};

But didn't compile, so I just used equality between same types.

To limit template (As of Question Q1) there a standard check:

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

Hope you have better suggestions, I still don't like this :) Thanks everyone!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文