提问人:Vero 提问时间:4/9/2022 最后编辑:Vero 更新时间:4/10/2022 访问量:82
模板化类之间的虚拟相等函数 (C++)
Virtual Equal Function between templated classes (C++)
问:
这个问题是这里的后续问题。目标是在非模板化类之间实现虚拟相等运算符。在这个问题中,我要求模板化类具有相同的目标。
#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:为了节省空间,我把所有内容都公开了,请忽略。
答:
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
是的。是的。但找不到解决方案!所以我刚刚破解了这个,请帮助任何对第一个问题有更好答案的人!
评论