standard operators

  • Follow


Dear all,

probably posted already a hundred times, but after working with c++
more than 6 years I still wondering why there is no standard compiler
generated operator== and operator<. If you use this classes for
sorting, you always have to fill in the operator, and 99% it will be
that every member is checked.

There is however an automatic generated operator=. Is the rationale
for this decision that the assignment operator= is used in more
contexts than the other operators?

Wkr,
me

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply gast128 (14) 11/27/2004 4:00:40 AM

> probably posted already a hundred times, but after working with c++
> more than 6 years I still wondering why there is no standard compiler
> generated operator== and operator<. If you use this classes for
> sorting, you always have to fill in the operator, and 99% it will be
> that every member is checked.

I suppose operator== could be defined automatically as memberwise 
comparison.  But the existing automatically generated member 
functions cause enough trouble as it is; why add more?  You usually 
have to implement them yourself (or suppress them) anyway and you 
must at least check that not doing so is correct.

There is no obvious general implementation of operator<.  And I 
disagree strongly that every member would be checked in operator< 
"99% [of the time]".

For many (most?) classes, operator< is ill-defined and should be 
illegal (e.g., std:complex, spatial vectors, etc.).  If it was 
automatically generated you'd end up having to suppress it for some 
classes just like you must sometimes suppress operator=.

I suppose a standard predicate function for use in sorting and sorted 
containers could be useful, but don't call it less or operator< 
unless it truly means "less than".

> There is however an automatic generated operator=. Is the rationale
> for this decision that the assignment operator= is used in more
> contexts than the other operators?

The point here is not to break C code/constructs when moving it to 
C++.  In C, assigning a struct to another does memberwise (or perhaps 
even bitwise) copy; that behavior had to be preserved in C++, hence 
the default operator=.  I think all of the automatically generated 
member functions have this rationale.

C structs can't be compared, so there were no backward compatibility 
issues there.


-- Mickey Moore

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Mickey 11/27/2004 9:29:21 PM


"gast128" <gast128@hotmail.com> wrote in message 
news:adb37573.0411261158.54984dd8@posting.google.com...

> There is however an automatic generated operator=. Is the rationale
> for this decision that the assignment operator= is used in more
> contexts than the other operators?

The rationale is that C allows assignment of structures, so it is useful for 
C++ to behave in a compatible way.


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Andrew 11/28/2004 2:10:40 AM

 > probably posted already a hundred times, but after working with c++
 > more than 6 years I still wondering why there is no standard compiler
 > generated operator== and operator<. If you use this classes for
 > sorting, you always have to fill in the operator, and 99% it will be
 > that every member is checked.

Not always.

 > There is however an automatic generated operator=. Is the rationale
 > for this decision that the assignment operator= is used in more
 > contexts than the other operators?

No. Backward compatibility with C.
With C's structs can be created, destroyed, copied and assigned but not
compared for equality.
And that is why C++ compilers have to be able to default generate ctors,
dtors, cctors, and assignment operators.

Stephen Howe



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Stephen 11/28/2004 11:37:28 AM

<adb37573.0411261158.54984dd8@posting.google.com>

On 26 Nov 2004 23:00:40 -0500, gast128@hotmail.com (gast128) wrote:

>Dear all,
>
>probably posted already a hundred times, but after working with c++
>more than 6 years I still wondering why there is no standard compiler
>generated operator== and operator<. 

The compiler does not necessairly know how you want to assert equality in
the structure or class.  For example, your data structure may contain
something like this:

class MyClass
{
protected:
	char *array; /* Pointer to a string. */
}

In this case, the compiler does not know how array should be evaluated for
a comparision, because this data type isn't always a null-terminated
string.  (It could instead be a buffer being filled for File I/O.)

>There is however an automatic generated operator=. Is the rationale
>for this decision that the assignment operator= is used in more
>contexts than the other operators?

Operator = is a copy operator, used to directly transfer the firleds of a
struct in C.  It works basically the same way in C++ where it directly
copies the members, in the same way it copies the fields of a struct.

The difference with C++ is that you can overload the operator so that you
can copy the contents of the buffer instead of just copying the pointer.  

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply bk039 11/28/2004 11:52:44 PM

"Stephen Howe" <sjhoweATdialDOTpipexDOTcom@eu.uu.net> wrote in message news:<41a9233b$0$8155$cc9e4d1f@news.dial.pipex.com>...
> > probably posted already a hundred times, but after working with c++
>  > more than 6 years I still wondering why there is no standard compiler
>  > generated operator== and operator<. If you use this classes for
>  > sorting, you always have to fill in the operator, and 99% it will be
>  > that every member is checked.
> 
> Not always.
Therefore I said 99%. In our projects, the operator== and operator<
are most needed in the context of putting them in a std::map or
std::set (or sorted std::vector), so that these containers can sort on
it, and that you can find them back.

If you develop large projects in c++, you have too think of a LOT of
things. If you add a member variable to a class, you have to see if it
has user defined operators and adjust them if needed. While this is
not difficult or spectacular, practice has learned us that this tend
to be forgotten, and this leads then to hard to track bugs.

It would be far more easier (also for the operator=) if the compiler
had built in support to do the operand for all its members. Then this
will never lead to a bug, like:

const X& X::operator=(const X& r)
{
   if (&r != this)
   {
      //call default
      __compiler_for_all_members_operator=(r);

      //override a member for deep copy 
      m_p = new ...
   }
   return *this;
}

C++ gives you a lot of flexibility also for large projects, but
sometimes it would be nice if the compiler could help here and there.

Besides this discussion about operators, there other things, but I
will come back to that in another thread.

Wkr,
me

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply gast128 11/28/2004 11:53:06 PM

"gast128" <gast128@hotmail.com> wrote in message
news:adb37573.0411280856.4c695db1@posting.google.com...
 > "Stephen Howe" <sjhoweATdialDOTpipexDOTcom@eu.uu.net> wrote in
 > message news:<41a9233b$0$8155$cc9e4d1f@news.dial.pipex.com>...
 >> > probably posted already a hundred times, but after working with
 >> > c++
 >>  > more than 6 years I still wondering why there is no standard
 >> compiler
 >>  > generated operator== and operator<. If you use this classes for
 >>  > sorting, you always have to fill in the operator, and 99% it
 >> will be
 >>  > that every member is checked.
 >>
 >> Not always.
 > Therefore I said 99%. In our projects, the operator== and operator<
 > are most needed in the context of putting them in a std::map or
 > std::set (or sorted std::vector), so that these containers can sort
 > on
 > it, and that you can find them back.
 >
 > If you develop large projects in c++, you have too think of a LOT of
 > things.

I disagree entirely.
Most, more than 50%, never mind 1%, of the classes I produce are small
classes with specific uses in specific contexts.
For these classes I actually spend more time disabling the copy
constructor and operator= than I do defining them.
Having additional things to disable would just make my job more
difficult.

Yes, when you are dealing with classes that represent "normal" data it
makes sense to use operator== and operator< but there are a great many
classes that don't represent "normal" data.
Some examples: classes that exist to ensure resource freeing; classes
that exist to do work on other classes; functional classes.
The mere concept of operator< does not make sense for any of these.

As you say, in a large project in c++ you do have to think of a lot of
things.
I think that the more explicit those things are the more usable the
language is - the ability to define operator< provides power, having
it happen automatically provides confusion.
I actually mandate that all non-trivial classes (and preferably the
trivial ones too) should declare their own copy constructor and
operator=, this way the users of the class can see what is happening.

Realistically it's probably a moot point anyway, adding this feature
now would break far too much.

What might be more use could be some kind of 'thing' that caused an
operation to take place on each member of a class.
Having an automatic way to call operator< on each base and then on
each member would ease the burden on you.
Having an automatic way to call swap() on each base and then on each
member would ease the burden on me.
It would need to be like some kind of in built function template (that
took either a functional object or a predicate as an argument).
I don't think it could be done with the facilities currently
available.
Any ideas anyone?

J.T.



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply James 11/29/2004 10:56:54 AM

> > Not always.
> Therefore I said 99%. In our projects, the operator== and operator<
> are most needed in the context of putting them in a std::map or
> std::set (or sorted std::vector), so that these containers can sort on
> it, and that you can find them back.

Lets do something concrete:

class Something
{
public:
    Something() : a_(0), b_(0), c_(0) {}
    Something(int a, int b, int c) : a_(a), b_(b), c_(c) {}
private:
    int     a_;
    int     b_;
    int     c_;
};

Now, what would you recommend for operator < that the compiler should
automatically generate if not specified? Bear in mind you would like to
insert Something object's in a std::set, so the compiler-generated operator
< has to obey strict weak ordering.

Stephen Howe



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Stephen 11/29/2004 9:49:13 PM

 > Lets do something concrete:
 >
 > class Something
 > {
 > public:
 >     Something() : a_(0), b_(0), c_(0) {}
 >     Something(int a, int b, int c) : a_(a), b_(b), c_(c) {}
 > private:
 >     int     a_;
 >     int     b_;
 >     int     c_;
 > };
 >
 > Now, what would you recommend for operator < that the compiler should
 > automatically generate if not specified? Bear in mind you would like to
 > insert Something object's in a std::set, so the compiler-generated operator
 > < has to obey strict weak ordering.

Well this function would implement such a strict weak ordering:

bool std_order_pred(const Something& Thing1, const Something& Thing2)
{
bool result = (Thing1.a_ < Thing2.a_);

result = result || ((Thing1.a_ == Thing2.a_)
                     && (Thing1.b_ < Thing2.b_));
result = result || ((Thing1.b_ == Thing2.b_)
                     && (Thing1.c_ < Thing2.c_));
// Where's the ||= operator when you need it? ;)

return result;
}

This is easily generalizable and is the conceptual equivalent of a
lexigraphical compare; you sort on the first non-equal member.
You can generalize for types without an operator== by changing
(Thing1.a_ == Thing2.a_) to !(Thing2.a_ < Thing1.a_).

But note I refused to use the name operator< for this function! This
function provides a useful ordering in some contexts, but not a
"natural" ordering.  operator< must mean "less than" or you are just
confusing people.  (I didn't name this predicate less() for the same
reason.)

I do often provide this function for my classes where operator< is
not appropriate -- which is almost all of them! -- so that I can put
them in associative containers easily later.


std::pair does provide an operator< (similar to above) for pragmatic
reasons; std:map would be confusing to implement and use without it.
But the committee refused (correctly, in my opinion) to provide a
specialization of std::less for std::complex, because there is no
"canonical" (fully mathematically consistent) ordering for complex
numbers.  (Note that I wouldn't be averse to the library including
some utility ordering predicates for such classes though -- just
don't name them operator< or std::less.)

-- Mickey Moore

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Mickey 11/30/2004 10:54:40 AM

 > For these classes I actually spend more time disabling the copy
 > constructor and operator= than I do defining them.
Boost has a nice boost::noncopyable base class, from which you can
derive. It serves also as a documentary hint. But actually this is
also a 'feature' which I don't like about c++ in large projects: most
of the classes are not copyable by default, or at least I haven't
think about it (e.g. due to deep copy), so I don't want my compiler to
generate the copy ctor/operator=. So now almost all classes which I
produce are derived from this boost::noncopyable.

 > Realistically it's probably a moot point anyway, adding this feature
 > now would break far too much.
I am aware of that, but c++ grows and grows and keeps its old
constructs, because of zillions legacy code. A cleanup would be nice,
perhaps like with c, where you can compile with the old k&r style.

 > What might be more use could be some kind of 'thing' that caused an
 > operation to take place on each member of a class.
 > Having an automatic way to call operator< on each base and then on
 > each member would ease the burden on you.
That's what I proposed in a previous mail. It solves many of my
problems. Typing is reduced to a minimum, and it has many advantages
while not creating a maintenance object. And you can always override
the members you want (e.g. for deep copying purposes, specialized
operator==) or not using it at all.

Are there other c++ guru's who can react on this?

Wkr,
me

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply gast128 11/30/2004 11:03:04 AM

In article <adb37573.0411291557.74fac7fa@posting.google.com>, gast128 
<gast128@hotmail.com> writes
> > What might be more use could be some kind of 'thing' that caused an
> > operation to take place on each member of a class.
> > Having an automatic way to call operator< on each base and then on
> > each member would ease the burden on you.
>That's what I proposed in a previous mail. It solves many of my
>problems. Typing is reduced to a minimum, and it has many advantages
>while not creating a maintenance object. And you can always override
>the members you want (e.g. for deep copying purposes, specialized
>operator==) or not using it at all.

Part of the explicit class proposal (N1717) from Lois Goldthwaite and 
myself provides a mechanism for telling a compiler to generate a default 
definition of a function. In the current proposal it is limited to the 
special member functions but if there was sufficient support it could be 
extended to other cases. However I would strongly resist introducing 
other implicit definitions, indeed part of the motive for the explicit 
class proposal is exactly that these implicit definitions are often 
unhelpful and have to be suppressed by using hacks.


-- 
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Francis 11/30/2004 11:13:10 PM

gast128@hotmail.com (gast128) wrote in message
news:<adb37573.0411261158.54984dd8@posting.google.com>...

> probably posted already a hundred times, but after working with c++
> more than 6 years I still wondering why there is no standard compiler
> generated operator== and operator<. If you use this classes for
> sorting, you always have to fill in the operator, and 99% it will be
> that every member is checked.

I don't know from where you got your statistics, but in 15 years of C++,
I don't think I've ever had a class where such a default generated <
would do the right thing.  And such a default == would be generally
wrong too, as soon as there are pointers.

> There is however an automatic generated operator=. Is the rationale
> for this decision that the assignment operator= is used in more
> contexts than the other operators?

The rationale is that it was a necessary evil, for reasons of C
compatiblity.  It's the same rationale which gives us a default
constructor, a copy constructor and a destructor.  Without those four,
you can't have a struct that works like a struct in C would.

Ideally, I think there wouldn't be any compiler generated defaults.  But
that would break C compatibility, and if we were going that route, there
are a lot of other things, like the declaration syntax, which need
fixing as well.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply kanze 11/30/2004 11:34:06 PM

> Boost has a nice boost::noncopyable base class, from which you can
> derive. It serves also as a documentary hint. But actually this is
> also a 'feature' which I don't like about c++ in large projects: most
> of the classes are not copyable by default, or at least I haven't
> think about it (e.g. due to deep copy), so I don't want my compiler to
> generate the copy ctor/operator=. So now almost all classes which I
> produce are derived from this boost::noncopyable.

So you want to remove the automatic copy ctor/operator= because they 
cause trouble, but you want to add an automatic operator== and 
operator<?

-- Mickey Moore

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Mickey 11/30/2004 11:53:24 PM

kanze@gabi-soft.fr wrote:

 > The rationale is that it was a necessary evil, for reasons of C
 > compatiblity.  It's the same rationale which gives us a default
 > constructor, a copy constructor and a destructor.  Without those four,
 > you can't have a struct that works like a struct in C would.
 >
 > Ideally, I think there wouldn't be any compiler generated defaults.  But
 > that would break C compatibility, and if we were going that route, there
 > are a lot of other things, like the declaration syntax, which need
 > fixing as well.

It could have been made so that classes didn't have any compiler
generated defaults while structs and unions kept C compatibility;
I wonder why it has not been made that way. A mere oversight?

-- 
Seungbeom Kim

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Seungbeom 12/1/2004 10:38:19 AM

kanze@gabi-soft.fr wrote:
> gast128@hotmail.com (gast128) wrote in message
> news:<adb37573.0411261158.54984dd8@posting.google.com>...
> 
> 
>>probably posted already a hundred times, but after working with c++
>>more than 6 years I still wondering why there is no standard compiler
>>generated operator== and operator<. If you use this classes for
>>sorting, you always have to fill in the operator, and 99% it will be
>>that every member is checked.
> 
> 
> I don't know from where you got your statistics, but in 15 years of C++,
> I don't think I've ever had a class where such a default generated <
> would do the right thing.  

Really?  You've never agreggated a couple of things into a struct for 
the purpose of using it as a map key?  The "default" < seems to work 
fine for std::pair.


-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply David 12/1/2004 10:13:10 PM

Seungbeom Kim <musiphil@bawi.org> wrote in message
news:<cojuqa$g6n$1@news.Stanford.EDU>...
> kanze@gabi-soft.fr wrote:

>  > The rationale is that it was a necessary evil, for reasons of C
>  > compatiblity.  It's the same rationale which gives us a default
>  > constructor, a copy constructor and a destructor.  Without those
>  > four, you can't have a struct that works like a struct in C would.

>  > Ideally, I think there wouldn't be any compiler generated defaults.
>  > But that would break C compatibility, and if we were going that
>  > route, there are a lot of other things, like the declaration
>  > syntax, which need fixing as well.

> It could have been made so that classes didn't have any compiler
> generated defaults while structs and unions kept C compatibility;
> I wonder why it has not been made that way. A mere oversight?

Perhaps the fact that structs and unions are classes?

I don't know the reasons why Stroustrup did it this way -- I've never
given it much thought; but in C++, there is no difference between a
struct and a class.  If I write:

    class C
    {
    public:
        int x ;
        int y ;
    } ;

it is exactly as if I wrote:

    struct C
    {
        int x ;
        int y ;
    } ;

Both are PODS, and guaranteed C compatible.

--
James Kanze           GABI Software         http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply kanze 12/2/2004 12:54:38 AM

Mickey Moore <mgmoore@austin.rr.com> wrote in message news:<MPG.1c16b821a9e47d6e9896c4@news-server.austin.rr.com>...
> > Boost has a nice boost::noncopyable base class, from which you can
> > derive. It serves also as a documentary hint. But actually this is
> > also a 'feature' which I don't like about c++ in large projects: most
> > of the classes are not copyable by default, or at least I haven't
> > think about it (e.g. due to deep copy), so I don't want my compiler to
> > generate the copy ctor/operator=. So now almost all classes which I
> > produce are derived from this boost::noncopyable.
> 
> So you want to remove the automatic copy ctor/operator= because they 
> cause trouble, but you want to add an automatic operator== and 
> operator<?
> 
A default operator== does less harm than a default operator=. If you
want to override the operator=, you probably also want to override a
possibly default operator==.

I don't see the conservatism here. Yesterday I saw again a not updated
operator==. It such a common mistake, so I don't see why people still
want to implement the operator== themselves. Like I said before, its
standard use is std::set or std::map. The exceptional case will be
that you override default behavior, for example if pointers are used.

And yes a default operator= is very handy, but probably should not be
generated automatically. But if you want to define it, I do not want
to implement every member for member assignment: this leads to bugs in
the long term. Same argument for operator==.

And by the way std::pair and boost::tuple does specify these
operators.

Wkr,
me

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply gast128 12/2/2004 1:02:38 AM

 >    class C
 >    {
 >    public:
 >        int x ;
 >        int y ;
 >    } ;
 >
 > it is exactly as if I wrote:
 >
 >    struct C
 >    {
 >        int x ;
 >        int y ;
 >    } ;
 >
 > Both are PODS, and guaranteed C compatible.

I seriously wish that "struct" had been reserved for PODs alone and any
non-POD would have to use "class".

Too late now :-(

Stephen Howe



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Stephen 12/2/2004 12:18:27 PM

kanze@gabi-soft.fr wrote:

 > Seungbeom Kim <musiphil@bawi.org> wrote in message
 > news:<cojuqa$g6n$1@news.Stanford.EDU>...
 >
 >> > Ideally, I think there wouldn't be any compiler generated defaults.
 >> > But that would break C compatibility, and if we were going that
 >> > route, there are a lot of other things, like the declaration
 >> > syntax, which need fixing as well.
 >
 >>It could have been made so that classes didn't have any compiler
 >>generated defaults while structs and unions kept C compatibility;
 >>I wonder why it has not been made that way. A mere oversight?
 >
 > Perhaps the fact that structs and unions are classes?
 >
 > I don't know the reasons why Stroustrup did it this way -- I've never
 > given it much thought; but in C++, there is no difference between a
 > struct and a class.  If I write:
 >
 >     class C
 >     {
 >     public:
 >         int x ;
 >         int y ;
 >     } ;
 >
 > it is exactly as if I wrote:
 >
 >     struct C
 >     {
 >         int x ;
 >         int y ;
 >     } ;
 >
 > Both are PODS, and guaranteed C compatible.

That's where my point lies, actually. A new keyword has been adopted,
and the difference is so small and trivial that it can be emulated by an
existing mechanism without much trouble. In fact, most class definitions
are written beginning with public bases and public members! Then why
should the new keyword have been adopted? It's a waste of name space.
(Not very rarely have I seen C programs with objects named "class".)

If we decided to adopt the new keyword, we could have taken more
advantage of it, by letting it inherit all the C compatibility burdens
no more and making it safer for real C++ classes which are not PODs.

-- 
Seungbeom Kim

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Seungbeom 12/2/2004 12:22:45 PM

Francis Glassborow <francis@robinton.demon.co.uk> wrote
 > Part of the explicit class proposal (N1717) from Lois Goldthwaite and
 > myself provides a mechanism for telling a compiler to generate a default
 > definition of a function. In the current proposal it is limited to the
 > special member functions but if there was sufficient support it could be
 > extended to other cases.

I'd like some automatic way to generate operator+ from operator+= (and
possibly vice-versa!), and so on. I suspect (but I can't prove) that
some compilers would be able to optimize this in ways that portable
code cannot, just as it already does on many platforms for integers.

 > However I would strongly resist introducing
 > other implicit definitions, indeed part of the motive for the explicit
 > class proposal is exactly that these implicit definitions are often
 > unhelpful and have to be suppressed by using hacks.

I'd be wary of removing them from the language, since so much depends on
them... but I resist even more strongly the idea of extending them
implicitly.

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply allan_w 12/2/2004 12:27:12 PM

In article <adb37573.0412010706.56b7bebe@posting.google.com>, gast128 
<gast128@hotmail.com> writes
>A default operator== does less harm than a default operator=. If you
>want to override the operator=, you probably also want to override a
>possibly default operator==.

And how would you define the default? Same value (or state) or same 
object? Both make sense.

-- 
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Francis 12/2/2004 7:09:48 PM

"Stephen Howe" <sjhoweATdialDOTpipexDOTcom@eu.uu.net> writes:

|  >    class C
|  >    {
|  >    public:
|  >        int x ;
|  >        int y ;
|  >    } ;
|  >
|  > it is exactly as if I wrote:
|  >
|  >    struct C
|  >    {
|  >        int x ;
|  >        int y ;
|  >    } ;
|  >
|  > Both are PODS, and guaranteed C compatible.
|
| I seriously wish that "struct" had been reserved for PODs alone and any
| non-POD would have to use "class".

I believe that is an artificial distinction, that says more about
implementation than a real tool for abstraction.

The keyword "class" was necessary in C with Classes, and C++ in its
early days, as a "psychological" revolution.  But it is semantically
redundant with "struct"; that is why I would find the distinction
artificial.  Note , that is not circular reasoning.

On the other hand, if "class" were to indicate that something is
allocated differently (e.g. on heap), then I would find the
distinction arguably justifiable.

-- 
                                                        Gabriel Dos Reis
                                            gdr@integrable-solutions.net

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Gabriel 12/3/2004 11:41:12 AM

In article <7f2735a5.0412011528.59d12b62@posting.google.com>, Allan W 
<allan_w@my-dejanews.com> writes
>I'd like some automatic way to generate operator+ from operator+= (and
>possibly vice-versa!), and so on. I suspect (but I can't prove) that
>some compilers would be able to optimize this in ways that portable
>code cannot, just as it already does on many platforms for integers.

Yes, I believe that in C# the compound operators are just defined in 
terms of the simple operators with the result that the compiler 
optimises as appropriate. I think, if enough people wanted it, we could 
achieve something similar in C++ by providing a syntax to tell the 
compiler to generate, for example, + from += or vice-versa.

>
> > However I would strongly resist introducing
> > other implicit definitions, indeed part of the motive for the explicit
> > class proposal is exactly that these implicit definitions are often
> > unhelpful and have to be suppressed by using hacks.
>
>I'd be wary of removing them from the language, since so much depends on
>them... but I resist even more strongly the idea of extending them
>implicitly.

Our proposal does not do that, but it does provide a syntax for 
declaring classes that do not have implicit generation of special member 
functions.

-- 
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply Francis 12/3/2004 2:30:59 PM

"Allan W" <allan_w@my-dejanews.com> wrote in message 
news:7f2735a5.0412011528.59d12b62@posting.google.com...
> I'd like some automatic way to generate operator+ from operator+= 
> (and
> possibly vice-versa!), and so on. I suspect (but I can't prove) that
> some compilers would be able to optimize this in ways that portable
> code cannot, just as it already does on many platforms for integers.

http://www.boost.org/libs/utility/operators.htm#smpl_oprs

It's not entirely automatic, but it's about as close as you are ever 
going to get.

J.T.
Please reply via the newsgroup 



      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply James 12/3/2004 2:33:19 PM

How about writing up a small pre-processor which does the job for you.
This way you can control what operators get added implicitly and then
pass your pre-processed souce code files to C++. Sounds like a good
middle of the road solution ???


allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0412011528.59d12b62@posting.google.com>...
> Francis Glassborow <francis@robinton.demon.co.uk> wrote
>  > Part of the explicit class proposal (N1717) from Lois Goldthwaite and
>  > myself provides a mechanism for telling a compiler to generate a default
>  > definition of a function. In the current proposal it is limited to the
>  > special member functions but if there was sufficient support it could be
>  > extended to other cases.
> 
> I'd like some automatic way to generate operator+ from operator+= (and
> possibly vice-versa!), and so on. I suspect (but I can't prove) that
> some compilers would be able to optimize this in ways that portable
> code cannot, just as it already does on many platforms for integers.
> 
>  > However I would strongly resist introducing
>  > other implicit definitions, indeed part of the motive for the explicit
>  > class proposal is exactly that these implicit definitions are often
>  > unhelpful and have to be suppressed by using hacks.
> 
> I'd be wary of removing them from the language, since so much depends on
> them... but I resist even more strongly the idea of extending them
> implicitly.
> 
>       [ See http://www.gotw.ca/resources/clcm.htm for info about ]
>       [ comp.lang.c++.moderated.    First time posters: Do this! ]

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Reply karve 12/3/2004 3:05:50 PM

David Abrahams <dave@boost-consulting.com> wrote in message
news:<ecadnadEZKTpTTDcRVn-1Q@rcn.net>...
> kanze@gabi-soft.fr wrote:
> > gast128@hotmail.com (gast128) wrote in message
> > news:<adb37573.0411261158.54984dd8@posting.google.com>...

> >>probably posted already a hundred times, but after working with c++
> >>more than 6 years I still wondering why there is no standard
> >>compiler generated operator== and operator<. If you use this classes
> >>for sorting, you always have to fill in the operator, and 99% it
> >>will be that every member is checked.

> > I don't know from where you got your statistics, but in 15 years of
> > C++, I don't think I've ever had a class where such a default
> > generated < would do the right thing.

> Really? You've never agreggated a couple of things into a struct for
> the purpose of using it as a map key? The "default" < seems to work
> fine for std::pair.

Does it?  I've never used it.  But then, I rarely use std::pair anyway.
The names of the fields aren't generally semantically related to what
the fields actually signify.

But I'm not necessarily against defining some sort of default for
std::less, although even then, I'd prefer some special name, say
std::ordering_predicate. As the situation currently stands, I would even
argue that the standard should provide a partial specialization for
std::less< std::complex >, for example, although it definitly shouldn't
define < for complex.

The operator < has an estabilished meaning.  Most of the time, I don't
define it, because it doesn't make sense.  In at least one case, I
defined it with semantics which would not be appropriate for an
associative container.  And I'm not the first -- it's usually defined
with inappropriate semantics for the built-in floating point types.
Given this, would you propose that:

 1. we require implementations to provide a compatible ordering for <
    over double and float (including for NaN's and Infinities),

 2. we should require implementations which don't have a compatible
    ordering for < to provide a specialization for std::less which does
    implement a compatible ordering, or

 3. using a float or a double in an associative container is undefined,
    or implementation defined, behavior?

Personally, I would sort of favor 2 (although 3 is the current status).

--
James Kanze           GABI Software         http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply kanze 12/3/2004 5:01:53 PM

25 Replies
74 Views

(page loaded in 0.18 seconds)


Reply: