Prevent equality comparison of sibling structs

  • A+
Category:Languages

I have a number of structs that are derived from the same base for the purpose of code reuse, but I do not want any form of polymorphism.

struct B {     int field;     void doStuff() {}     bool operator==(const B& b) {         return field == b.field;     } };  struct D1 : public B {     D1(int field) : B{field} {} }; struct D2 : public B {     D2(int field) : B{field} {} }; 

Structs D1 and D2 (and more similar structs) derive from B to share common fields and methods, so that I would not need to duplicate those fields and methods in each of the derived classes.

Struct B is never instantiated; I only use instances of D1 and D2. Furthermore, D1 and D2 are not supposed to interact with each other at all. Essentially, I do not want any polymorphic behaviour: D1 and D2, for all purposes, should act as unrelated structs.

I would like any D1 to be compared with other D1s for equality, and any D2 to be compared with other D2s for equality. Since D1 and D2 don't contain any fields, it would seem appropriate to define an equality operator in struct B.

However, (as expected) I get the following interaction between D1 and D2:

int main() {     D1 d1a(1);     D1 d1b(1);     D2 d2(1);      assert(d1a == d1b); // good      assert(d1a == d2); // oh no, it compiles! } 

I don't want to be able to compare D1 with D2 objects, because for all purposes, they should act as if they are unrelated.

How can I make the last assertion be a compile error without duplicating code? Defining the equality operator separately for D1 and D2 (and all the other similar structs) would mean code duplication, so I wish to avoid that if possible.

 


You can use CRTP to define operator == only on the reference to final type:

template<typename T> struct B {     int field;     void doStuff() {}     bool operator==(const T& b) {         return field == b.field;     } };  struct D1 : public B<D1> {     D1(int field) : B{field} {} }; struct D2 : public B<D2> {     D2(int field) : B{field} {} }; 

This causes the first assert to compile and the second one to be rejected.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: