There is a not to the operator==
related solution possible. You can generate the related code from a definition table with the help of so called X-Macro. The table could look like
#define MEMBER_TBL \
/*type ,name ,default*/ \
X(int ,_(i) ,42 ) \
X(float ,_(f) ,3.14 ) \
X(std::string , t ,"Hello") \
The _()
stuff is needed to avoid a trailing ,
on generation the std::tie()
call. Make sure that the last element is w.o. _()
. The usage to generate the members is:
struct Foo
{
#define _(x) x
#define X(type, name, default) type name{default};
MEMBER_TBL
#undef X
#undef _
}
This generates:
struct Foo
{
int i{42}; float f{3.14}; std::string t{"Hello"};
}
To generate the operator==
you can use:
bool operator==(Foo const& other) const {
return std::tie(
#define _(x) x,
#define X(type, name, default) this->name
MEMBER_TBL
#undef X
) == std::tie(
#define X(type, name, default) other.name
MEMBER_TBL
#undef X
#undef _
);
}
which results into
bool operator==(Foo const& other) const {
return std::tie(
this->i, this->f, this->t
) == std::tie(
other.i, other.f, other.t
);
}
To add new members you can add simply a new entry to the first table. Everything else is generated automatically.
Another advantage is, you can add simply a dump()
method like
void print(void) const {
#define STR(x) #x
#define _(x) x
#define X(type, name, default) \
std::cout << \
STR(name) << ": " << name << " ";
MEMBER_TBL
#undef X
#undef _
#undef STR
std::cout << std::endl;
}
which results into
void print() const {
std::cout << "i" << ": " << i << " "; std::cout << "f" << ": " << f << " "; std::cout << "t" << ": " << t << " ";
std::cout << std::endl;
}
Every information regarding to the members could be added to the table at one place (single point of information) and extracted elsewhere needed.
A working Demo.