Topic: Proposal: Implicit generated relational & equality operators


Author: tslettebo@chello.no.nospam (=?iso-8859-1?Q?Terje_Sletteb=F8?=)
Date: Tue, 24 Jun 2003 03:40:20 +0000 (UTC)
Raw View
"Anders Dalvander" <google@dalvander.com> wrote in message
news:d04c84a9.0306150732.5c263b8f@posting.google.com...
> There are the implicit generated default constructor, the implicit
> generated copy constructor and the implicit generated assignment
> operator. Why aren't any other operators, especially the relational &
> equality operators, implicit generated in the same way? It would be
> much easier to write code that just works, without writing the same
> looking code over and over again. If the programmer wants to he/she
> could implement his/her own implementation of the operator that would
> replace the implicit generated one.
>
> Example:
> struct foo
> {
>    // Proposal:
>    // Implicit generated less-than operator
>    // bool operator<(const foo&) const { ... }
>    // Implicit generated less-than-or-equal-to operator
>    // bool operator<=(const foo&) const { ... }
>    // Implicit generated greater-than operator
>    // bool operator>(const foo&) const { ... }
>    // Implicit generated greater-than-or-equal-to operator
>    // bool operator>=(const foo&) const { ... }
>    // Implicit generated equal-to operator
>    // bool operator==(const foo&) const { ... }
>    // Implicit generated not-equal-to operator
>    // bool operator!=(const foo&) const { ... }
>
>    int i;
>    int j;
> };
>
> int main()
> {
>    foo foo1, foo2;
>    if (foo1 > foo2)
>    {
>       // Do something.
>    }
> }

How would they be defined?

For example in this case, what constitutes that an object of "foo" is
less than another? If both "i" and "j" are less than the other one? What
if one is less, one is bigger? What if you have elements which have no
obvious ordering, such as std::complex? It has operator == and !=, but
not <, etc.

I think it's sensible that operator <, etc. aren't defined by default,
for this reason. It might be argued for a default operator == and !=,
doing a memberwise comparison (like operator = does a memberwise
assignment), though.

In any case, once you've defined operator < and ==, you can generate the
others using boost::operators
(http://www.boost.org/libs/utility/operators.htm).


Regards,

Terje

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: sebmol@yahoo.com ("Sebastian Moleski")
Date: Tue, 24 Jun 2003 03:46:17 +0000 (UTC)
Raw View
"Anders Dalvander" <google@dalvander.com> wrote in message
news:d04c84a9.0306150732.5c263b8f@posting.google.com...
> There are the implicit generated default constructor, the implicit
> generated copy constructor and the implicit generated assignment
> operator. Why aren't any other operators, especially the relational &
> equality operators, implicit generated in the same way? It would be
> much easier to write code that just works, without writing the same
> looking code over and over again. If the programmer wants to he/she
> could implement his/her own implementation of the operator that would
> replace the implicit generated one.

And how is the compiler going to implement these implicit operators? With
the example you gave, there's a variety of ways to define ordering. Which
one should the compiler choose?

sm


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: xleobx@qmailcomq.com
Date: Fri, 27 Jun 2003 17:38:31 +0000 (UTC)
Raw View
Anders Dalvander <google@dalvander.com> wrote:

>    // Proposal:
>    // Implicit generated less-than operator
>    // bool operator<(const foo&) const { ... }
>    // Implicit generated less-than-or-equal-to operator
>    // bool operator<=(const foo&) const { ... }
>    // Implicit generated greater-than operator
>    // bool operator>(const foo&) const { ... }
>    // Implicit generated greater-than-or-equal-to operator
>    // bool operator>=(const foo&) const { ... }
>    // Implicit generated equal-to operator
>    // bool operator==(const foo&) const { ... }
>    // Implicit generated not-equal-to operator
>    // bool operator!=(const foo&) const { ... }

While it is feasible to rationalize the implicit
equality/inequality operators (their semantics
follows from the semantics of the implicit copy constructor
and the assignment operator), what should be the
functionality of implicitly generated operator< ?

And, while we're at it, implicit member-operators
new and delete (defined as calls to ::operator new and
::operator delete respectively) are, IMO, a must
for the sake of orthogonality.

 Leo

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: MattDelB@nospam.com ("Matthew Del Buono")
Date: Fri, 27 Jun 2003 17:39:05 +0000 (UTC)
Raw View
Note that the default constructor practically does nothing. The copy
constructor and = operator both have defined purposes, however. They both
copy all data items over from one class/struct to another. Each data item is
copied directly. The (in)equality operators make no sense to have default
behavior. Unlike the copy constructor and = operator, they must have a
defined return value (not just foo&). Therefore, they must perform some kind
of test. But what is there to test? How could the compiler possibly know
what to test? There could be three variables! Basically what you're asking
for is undefined behavior. It simply doesn't make sense to create those
operators: there could be no way to be sure of what to test.
----------------------------------------------------
MiniDisc_2k2
To send e-mail, replace nospam.com
with cox.net

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: chandra.kumar@oracle.com (Chandra Shekhar Kumar)
Date: Fri, 27 Jun 2003 17:54:24 +0000 (UTC)
Raw View
for the primitive types (int, float etc.) it makes sense and it is there, but
for user-defined types, what cud  the default generated relational & equality
operators will do....coz assuming that it is there(the default ones ), it is
sure that nobody will use this default behaviour....so why have the default
ones

Anders Dalvander wrote:

> There are the implicit generated default constructor, the implicit
> generated copy constructor and the implicit generated assignment
> operator. Why aren't any other operators, especially the relational &
> equality operators, implicit generated in the same way? It would be
> much easier to write code that just works, without writing the same
> looking code over and over again. If the programmer wants to he/she
> could implement his/her own implementation of the operator that would
> replace the implicit generated one.
>
> Example:
> struct foo
> {
>    // As of now:
>    // Implicit generated default constructor
>    // foo() { ... }
>    // Implicit generated copy constructor
>    // foo(const foo&) { ... }
>    // Implicit generated assignment operator
>    // foo& operator=(const foo&) { ... }
>
>    // Proposal:
>    // Implicit generated less-than operator
>    // bool operator<(const foo&) const { ... }
>    // Implicit generated less-than-or-equal-to operator
>    // bool operator<=(const foo&) const { ... }
>    // Implicit generated greater-than operator
>    // bool operator>(const foo&) const { ... }
>    // Implicit generated greater-than-or-equal-to operator
>    // bool operator>=(const foo&) const { ... }
>    // Implicit generated equal-to operator
>    // bool operator==(const foo&) const { ... }
>    // Implicit generated not-equal-to operator
>    // bool operator!=(const foo&) const { ... }
>
>    int i;
>    int j;
> };
>
> int main()
> {
>    foo foo1, foo2;
>    if (foo1 > foo2)
>    {
>       // Do something.
>    }
> }
>
> // Anders Dalvander
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: google@dalvander.com (Anders Dalvander)
Date: Fri, 20 Jun 2003 19:33:55 +0000 (UTC)
Raw View
There are the implicit generated default constructor, the implicit
generated copy constructor and the implicit generated assignment
operator. Why aren't any other operators, especially the relational &
equality operators, implicit generated in the same way? It would be
much easier to write code that just works, without writing the same
looking code over and over again. If the programmer wants to he/she
could implement his/her own implementation of the operator that would
replace the implicit generated one.

Example:
struct foo
{
   // As of now:
   // Implicit generated default constructor
   // foo() { ... }
   // Implicit generated copy constructor
   // foo(const foo&) { ... }
   // Implicit generated assignment operator
   // foo& operator=(const foo&) { ... }

   // Proposal:
   // Implicit generated less-than operator
   // bool operator<(const foo&) const { ... }
   // Implicit generated less-than-or-equal-to operator
   // bool operator<=(const foo&) const { ... }
   // Implicit generated greater-than operator
   // bool operator>(const foo&) const { ... }
   // Implicit generated greater-than-or-equal-to operator
   // bool operator>=(const foo&) const { ... }
   // Implicit generated equal-to operator
   // bool operator==(const foo&) const { ... }
   // Implicit generated not-equal-to operator
   // bool operator!=(const foo&) const { ... }

   int i;
   int j;
};

int main()
{
   foo foo1, foo2;
   if (foo1 > foo2)
   {
      // Do something.
   }
}

// Anders Dalvander

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: do-not-spam-ben.hutchings@businesswebsoftware.com (Ben Hutchings)
Date: Tue, 24 Jun 2003 01:44:31 +0000 (UTC)
Raw View
In article <d04c84a9.0306150732.5c263b8f@posting.google.com>,
Anders Dalvander wrote:
> There are the implicit generated default constructor, the implicit
> generated copy constructor and the implicit generated assignment
> operator. Why aren't any other operators, especially the relational &
> equality operators, implicit generated in the same way?

It's arguably undesirable that the copy constructor and assignment
operator are implicitly generated for a type defined with the 'class'
keyword, since many user-defined types should not be copiable.  Any
extension to the implicit members is even less likely to be generally
useful.

Many user-defined types do not have a meaningful equality relation and
I think relatively few have a usual ordering (as opposed to several
possible orderings).

> It would be
> much easier to write code that just works, without writing the same
> looking code over and over again. If the programmer wants to he/she
> could implement his/her own implementation of the operator that would
> replace the implicit generated one.
<snip>

You haven't explained how the generated operators would work, anyway,
though I'm guessing you intend something like this:

struct foo
{
    bool operator<(const foo&) const
    {
        return i < other.i || i == other.i && j < other.j;
    }
    bool operator<=(const foo& other) const
    {
        return i < other.i || i == other.i && j <= other.j;
    }
    // similarly for other relations

    int i;
    int j;
};

Which members should be compared, and in what order?  What about
base classes?

In what cases would the implicit generation be disabled, other than
where the class definition includes explicit declarations or
definitions of the functions?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]