patterncppMinor
Implementing C++ relational operators generator
Viewed 0 times
relationalimplementingoperatorsgenerator
Problem
Once you define the `
-
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
Are my problems over with this trick?
Here's a demo of the code working.
- 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
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.
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.