Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct member equality without overloading operator== in C++

Is it possible to define some kind of template that can create a generic comparable operator for structs?

For example is it possible for something like this?

struct A
{
    int one;
    int two;
    int three;
};
bool AreEqual()
{
    A a {1,2,3};
    A b {1,2,3};
    
    return ComparableStruct<A>(a) == ComparableStruct<A>(b);
}

All this does is a field by field comparison of the structs. You can assume all fields are of basic types or have overloaded operator==.

I have a lot of structs like this and it would save me a lot of time if I can just put it in a template or something for comparison rather than defining an operator== for every single struct. Thanks!

Update

It seems like this is not possible with C++. I wonder why this is voted out of C++ proposals, if anyone has the reasons let us know!

For solution that works with basic types only see solution by R Sahu.

like image 519
Nah Avatar asked Jan 06 '17 04:01

Nah


People also ask

Does overloading == also overload !=?

NO. There is no such requirement that you Must overload != If you need to overload == . However,it is a good practice that you Should overload operators related to each other.

Can the assignment (=) operator be applied to structs?

The assignment operator works with structures.

Is there operator overloading in C?

C does not support operator overloading (beyond what it built into the language).

How do I compare two structs in CPP?

yes,we can compare by using thir addresses. If the 2 structures variable are initialied with calloc or they are set with 0 by memset so you can compare your 2 structures with memcmp. It is possible to use memcmp if: 1) the structs contain no floating-point fields.


2 Answers

Is it possible to define some kind of template that can create a generic comparable operator for structs?

If the struct has no padding, you can use:

template <typename T>
struct ComparableStruct
{
   ComparableStruct(T const& a) : a_(a) {}
   bool operator==(ComparableStruct const& rhs) const
   {
      return (std::memcmp(reinterpret_cast<char const*>(&a_), reinterpret_cast<char const*>(&rhs.a_), sizeof(T)) == 0);
   }

   T const& a_;
};

Better yet, you can use a function template.

template <typename T>
bool AreEqual(T cost& a, T const& b)
{
   return (std::memcmp(reinterpret_cast<char const*>(&a), reinterpret_cast<char const*>(&b), sizeof(T)) == 0);
}

If the struct has any padding, there is no guarantee that use of std::memcmp will work to compare two objects.

like image 82
R Sahu Avatar answered Oct 26 '22 23:10

R Sahu


Look at https://github.com/apolukhin/magic_get. This library can automagically generate comparison operators for some fairly simple structs.

#include <iostream>
#include <boost/pfr/flat/global_ops.hpp>

struct S {
    char c;
    int i;
    double d;
};

int main() {
    S s1{'a', 1, 100.500};
    S s2 = s1;
    S s3{'a', 2, 100.500};

    std::cout << "s1 " << ((s1 == s2) ? "==" : "!=") << " s2\n";
    std::cout << "s1 " << ((s1 == s3) ? "==" : "!=") << " s3\n";
}

// Produces
// s1 == s2
// s1 != s3
like image 35
Grisha Avatar answered Oct 27 '22 00:10

Grisha