|
Prev: Optimizing away copy constructors
Next: "strict weak ordering" requirement of compare argument for std::set
From: dizzy on 15 Jan 2008 20:14 bourez(a)gmail.com wrote: > Hi, Hello > When including the .h file with a class definition having operator== > defined, I would like also to automatically provide this class with > operator!= without giving the implementation, but by reusing an > existing one (the one defined in std::rel_ops). Actually, I would like > to explicitly instantiate (for my class only) the implementation of > std::rel_ops::operator!=, but in the namespace of my class. > > Is there a way to achieve this ? I can think of several solutions. One is of course to have a macro that you "instantiate" in your class definition. The other is using templates to do the macro work with inheritance and CRTP, example: template<typename T> struct notequal_operator { bool operator!=(T const& arg) const { return !(static_cast<T const*>(this)->operator==(arg)); } }; struct MyClass: notequal_operator<MyClass> { bool operator==(MyClass const& arg) const { ... } }; Of course if you worry about inheritance adding the "is a" relation, you could use private inheritance and add a "using" in MyClass definition to export the inherited operator!=. Notice however that for overloading operator==/operator!= you should prefer non member versions over the member ones. This is (at least from what I can remember) to enable equal conversions on the arguments (since ==/!= operators should be symetric to what happens to any of the arguments this makes sense). For example imagine this code: struct MyClass { MyClass(int = 0) {} // enable implicit conversion (and default ctor) bool operator==(MyClass const&) const { return false; } }; int main() { MyClass a, b; a == b; // works as expected a == 10; // also works (as expected) 10 == a; // does not work, but it should IMO since it should // not matter if it is first or second argument } Imagine how bad it would be if with our current "char const*" to std::string implicit conversion we couldn't do things as "if ("text" == str)...". Making the ==/!= operators non members will enable that conversion to work on both arguments. -- Dizzy [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Francis Glassborow on 16 Jan 2008 02:16
dizzy wrote: > > Imagine how bad it would be if with our current "char const*" to std::string > implicit conversion we couldn't do things as "if ("text" == str)...". > Making the ==/!= operators non members will enable that conversion to work > on both arguments. > To the theoretical purist such things might matter, and I guess there might be human languages where placing the literal first in a comparison is normal but in every human language where I know the details of comparisons writing something like "text" compares equal to is unnatural. So I would have no problem with if("text" == str) failing to compile. I would have a problem with it compiling and doing something different to the natural if(str == "text") There are operators that cause surprises if they are not defined as free functions but comparison operators are not among them (at least for me). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |