HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Implementing C++ relational operators generator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
relationalimplementingoperatorsgenerator

Problem

Once you define the `

  • Is there a time bomb in this code?



-
While trying to use this code with classes that already defined one of { >, ==, !=, = } I had ambiguity problems. The implementation I opted for (also the one existing in the linked Github repository) is tweaked like so

// inside the relational struct
friend bool operator>(relational const &lhs, relational const &rhs)
{ // functions that involve implicit conversion are less favourable in overload resolution
        return (T const&)rhs < (T const&)lhs; 
}


Are my problems over with this trick?

Here's a demo of the code working.

Solution

The problem I see is that it requires that the class be derived from relational, which is not a very durable design. Instead, why not use the fact that "substitution failure is not an error" (which has the regrettable but commonly used abbreviation SFINAE). the use of real functions is preferred over the instantiation of templates. That is, if an operator= in terms of ` respectively.

The result is that if any of the comparisons
or >= are defined, then all of the other comparisons are also available.

Edit: I should probably have pointed out why this is different from
std::rel_ops. With std::rel_ops, in order to have all six relative operators, you must define operator is defined in terms of = which is defined using >`. This arguably adds flexibility, but it also means that it's possible that the performance is not as good because a comparison may go through several templated function instantiations.

Further, if none of those operators is defined, that circular definition will mean infinite recursion at runtime until your stack is exhausted, putting this set of templates into the category of "perhaps more dangerous than clever" so Caveat lector.

Code Snippets

template<typename T>
bool operator> (T const &lhs, T const &rhs) { return !(lhs <= rhs); }
template<typename T>
bool operator< (T const &lhs, T const &rhs) { return !(lhs >= rhs); }
template<typename T>
bool operator==(T const &lhs, T const &rhs) { return lhs <= rhs && lhs >= rhs; }
template<typename T>
bool operator!=(T const &lhs, T const &rhs) { return !(rhs == lhs); }
template<typename T>
bool operator<=(T const &lhs, T const &rhs) { return lhs < rhs || (!(rhs < lhs)); }
template<typename T>
bool operator>=(T const &lhs, T const &rhs) { return lhs > rhs || (!(rhs > lhs)); }

Context

StackExchange Code Review Q#48622, answer score: 3

Revisions (0)

No revisions yet.