grr... this old nut

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • grahamo

    grr... this old nut

    I have done this before but it keeps eluding me when I revisit it...

    I have a class employee defined with;

    friend employee operator+(const employee& e1, const employee& e2) ;


    Now I know I can invoke that version of the operator by using
    something like;


    employee e1, e2;

    employee e3 = operator+(e1,e2 );


    however I know there are other ways to have it invoked...there by
    illustrating its use. What other ways are there? I thought


    employee e4 = e1+e2+e3;

    would do the trick but that doesn't invoke it (using latest G++
    compiler).


    any help much appreciated.


    cheers

    GrahamO
  • John Harrison

    #2
    Re: grr... this old nut


    "grahamo" <graham_walsh50 @hotmail.com> wrote in message
    news:79528aa8.0 407130440.4332d 0fb@posting.goo gle.com...[color=blue]
    > I have done this before but it keeps eluding me when I revisit it...
    >
    > I have a class employee defined with;
    >
    > friend employee operator+(const employee& e1, const employee& e2) ;
    >
    >
    > Now I know I can invoke that version of the operator by using
    > something like;
    >
    >
    > employee e1, e2;
    >
    > employee e3 = operator+(e1,e2 );
    >
    >
    > however I know there are other ways to have it invoked...there by
    > illustrating its use. What other ways are there? I thought
    >
    >
    > employee e4 = e1+e2+e3;
    >
    > would do the trick but that doesn't invoke it (using latest G++
    > compiler).
    >
    >
    > any help much appreciated.
    >
    >
    > cheers
    >
    > GrahamO[/color]

    It should work like that. Can you supply a complete program and explain what
    happens instead.

    john


    Comment

    • Howard

      #3
      Re: grr... this old nut


      "John Harrison" <john_andronicu s@hotmail.com> wrote in message
      news:2li4siFcid otU1@uni-berlin.de...[color=blue]
      >
      > "grahamo" <graham_walsh50 @hotmail.com> wrote in message
      > news:79528aa8.0 407130440.4332d 0fb@posting.goo gle.com...[color=green]
      > > I have done this before but it keeps eluding me when I revisit it...
      > >
      > > I have a class employee defined with;
      > >
      > > friend employee operator+(const employee& e1, const employee& e2) ;
      > >
      > >
      > > Now I know I can invoke that version of the operator by using
      > > something like;
      > >
      > >
      > > employee e1, e2;
      > >
      > > employee e3 = operator+(e1,e2 );
      > >
      > >
      > > however I know there are other ways to have it invoked...there by
      > > illustrating its use. What other ways are there? I thought
      > >
      > >
      > > employee e4 = e1+e2+e3;
      > >
      > > would do the trick but that doesn't invoke it (using latest G++
      > > compiler).
      > >
      > >
      > > any help much appreciated.
      > >
      > >
      > > cheers
      > >
      > > GrahamO[/color]
      >
      > It should work like that. Can you supply a complete program and explain[/color]
      what[color=blue]
      > happens instead.
      >
      > john[/color]

      Doesn't the function have to be const in order to chain it like that, since
      e1+e2+e3 creates a temporary (or two)?

      -Howard

      [color=blue]
      >
      >[/color]


      Comment

      • Peter van Merkerk

        #4
        Re: grr... this old nut

        grahamo wrote:
        [color=blue]
        > I have done this before but it keeps eluding me when I revisit it...
        >
        > I have a class employee defined with;
        >
        > friend employee operator+(const employee& e1, const employee& e2) ;[/color]

        It would help if you post minimal, yet compilable code that demonstrates
        the problem you are having. Do you mean that operator+() is a member
        function of the employee class?
        In that case it should only have one employee argument:

        class employee
        {
        public:
        employee operator+(const employee& e2)
        {
        // Return the sum of *this and e2...
        }
        };

        You could also declare the operator+() function outside the scope of the
        employee class. In that case you do need two employee arguments. Since
        only friends can touch your employee's private parts, you may have to
        make operator+(const employee& e1, const employee& e2) a friend of employee:

        class employee
        {
        // Only needed if operator+() needs to have access to employees
        // privates.
        friend employee operator+(const employee& e1, const employee& e2);

        // ...other stuff...

        };

        employee operator+(const employee& e1, const employee& e2)
        {
        // Return the sum of e1 and e2...
        }

        Anyway, defining an operator+() for employees seems to be an excellent
        example of inappropriate use of operator overloading. To me it is not
        obvious what happens if you add two employees. Does it mean that e1 and
        e2 have intercourse and produce another employee... in that case the
        multiplication operator would be more appropriate ;-)

        --
        Peter van Merkerk
        peter.van.merke rk(at)dse.nl

        Comment

        • Andre Kostur

          #5
          Re: grr... this old nut

          "Howard" <alicebt@hotmai l.com> wrote in
          news:NGSIc.8985 6$OB3.66024@bgt nsc05-news.ops.worldn et.att.net:
          [color=blue]
          >
          > "John Harrison" <john_andronicu s@hotmail.com> wrote in message
          > news:2li4siFcid otU1@uni-berlin.de...[color=green]
          >>
          >> "grahamo" <graham_walsh50 @hotmail.com> wrote in message
          >> news:79528aa8.0 407130440.4332d 0fb@posting.goo gle.com...[color=darkred]
          >> > I have done this before but it keeps eluding me when I revisit
          >> > it...
          >> >
          >> > I have a class employee defined with;
          >> >
          >> > friend employee operator+(const employee& e1, const employee& e2)
          >> > ;
          >> >
          >> >
          >> > Now I know I can invoke that version of the operator by using
          >> > something like;
          >> >
          >> >
          >> > employee e1, e2;
          >> >
          >> > employee e3 = operator+(e1,e2 );
          >> >
          >> >
          >> > however I know there are other ways to have it invoked...there by
          >> > illustrating its use. What other ways are there? I thought
          >> >
          >> >
          >> > employee e4 = e1+e2+e3;
          >> >
          >> > would do the trick but that doesn't invoke it (using latest G++
          >> > compiler).
          >> >
          >> >
          >> > any help much appreciated.
          >> >
          >> >
          >> > cheers
          >> >
          >> > GrahamO[/color]
          >>
          >> It should work like that. Can you supply a complete program and
          >> explain[/color]
          > what[color=green]
          >> happens instead.
          >>
          >> john[/color]
          >
          > Doesn't the function have to be const in order to chain it like that,
          > since e1+e2+e3 creates a temporary (or two)?[/color]

          It's a freestanding function (it's not a member function, only a friend),
          it can't be const.

          Comment

          • Howard

            #6
            Re: grr... this old nut


            "Andre Kostur" <nntpspam@kostu r.net> wrote in message
            news:Xns9525567 13C81Fnntpspamk osturnet@207.35 .177.135...[color=blue]
            > "Howard" <alicebt@hotmai l.com> wrote in
            > news:NGSIc.8985 6$OB3.66024@bgt nsc05-news.ops.worldn et.att.net:
            >[color=green]
            > >
            > > "John Harrison" <john_andronicu s@hotmail.com> wrote in message
            > > news:2li4siFcid otU1@uni-berlin.de...[color=darkred]
            > >>
            > >> "grahamo" <graham_walsh50 @hotmail.com> wrote in message
            > >> news:79528aa8.0 407130440.4332d 0fb@posting.goo gle.com...
            > >> > I have done this before but it keeps eluding me when I revisit
            > >> > it...
            > >> >
            > >> > I have a class employee defined with;
            > >> >
            > >> > friend employee operator+(const employee& e1, const employee& e2)
            > >> > ;
            > >> >
            > >> >
            > >> > Now I know I can invoke that version of the operator by using
            > >> > something like;
            > >> >
            > >> >
            > >> > employee e1, e2;
            > >> >
            > >> > employee e3 = operator+(e1,e2 );
            > >> >
            > >> >
            > >> > however I know there are other ways to have it invoked...there by
            > >> > illustrating its use. What other ways are there? I thought
            > >> >
            > >> >
            > >> > employee e4 = e1+e2+e3;
            > >> >
            > >> > would do the trick but that doesn't invoke it (using latest G++
            > >> > compiler).
            > >> >
            > >> >
            > >> > any help much appreciated.
            > >> >
            > >> >
            > >> > cheers
            > >> >
            > >> > GrahamO
            > >>
            > >> It should work like that. Can you supply a complete program and
            > >> explain[/color]
            > > what[color=darkred]
            > >> happens instead.
            > >>
            > >> john[/color]
            > >
            > > Doesn't the function have to be const in order to chain it like that,
            > > since e1+e2+e3 creates a temporary (or two)?[/color]
            >
            > It's a freestanding function (it's not a member function, only a friend),
            > it can't be const.[/color]

            Oops! :-) I was thinking of a member function returning a reference. I
            realized my mistake immediately, and cancelled my post seconds after sending
            it, but I guess it still shows up for some people. Sorry.

            -Howard



            Comment

            • Ali Cehreli

              #7
              Re: grr... this old nut

              On Tue, 13 Jul 2004 05:40:58 -0700, grahamo wrote:
              [color=blue]
              > I have done this before but it keeps eluding me when I revisit it...
              >
              > I have a class employee defined with;
              >
              > friend employee operator+(const employee& e1, const employee& e2) ;[/color]

              It is better to implement the free operator+ in terms of the member
              operator+=, which makes the friendship unnecessary.

              [...]
              [color=blue]
              > employee e4 = e1+e2+e3;
              >
              > would do the trick but that doesn't invoke it (using latest G++
              > compiler).[/color]

              Here is an example:

              class C
              {
              int i_;

              public:

              explicit C(int i)
              :
              i_(i)
              {}

              C & operator+= (C const & other)
              {
              i_ += other.i_;
              return *this;
              }

              int value() const
              {
              return i_;
              }
              };

              C operator+ (C const & lhs, C const & rhs)
              {
              C result(lhs);
              return result += rhs;
              }

              #include <iostream>

              int main()
              {
              C const one(1);
              C const two(2);
              C const three(3);
              C const result = one + two + three;

              std::cout << result.value() << '\n';
              }

              Ali

              Comment

              • Howard

                #8
                Re: grr... this old nut


                "Ali Cehreli" <acehreli@yahoo .com> wrote in message
                news:pan.2004.0 7.13.11.21.04.9 05329.8388@yaho o.com...
                [color=blue]
                > C operator+ (C const & lhs, C const & rhs)
                > {
                > C result(lhs);
                > return result += rhs;
                > }
                >[/color]

                Is that legal? I'd think that it might invoke undefined behavior (but I'm
                probably wrong. :-)) Even if it works, though, I'd prefer to break it into
                two lines:

                C operator+ (C const & lhs, C const & rhs)
                {
                C result(lhs);
                result += rhs;
                return result;
                }

                Operator += returns a reference to result, which is then returned as n
                object (not a reference), so I guess a copy must be made there (skipping
                over possible optimizations, of course). So I guess it's ok, but it just
                looks ugly to me, and performs multiple actions on one line (calling the
                operator and then returning a copy of that result), something I'm loathe to
                do.

                -Howard


                Comment

                • Ali Cehreli

                  #9
                  Re: grr... this old nut

                  On Tue, 13 Jul 2004 12:43:48 -0700, Howard wrote:

                  [color=blue]
                  > "Ali Cehreli" <acehreli@yahoo .com> wrote in message
                  > news:pan.2004.0 7.13.11.21.04.9 05329.8388@yaho o.com...
                  >[color=green]
                  >> C operator+ (C const & lhs, C const & rhs) {
                  >> C result(lhs);
                  >> return result += rhs;
                  >> }
                  >>
                  >>[/color]
                  > Is that legal? I'd think that it might invoke undefined behavior (but
                  > I'm probably wrong. :-)) Even if it works, though, I'd prefer to break
                  > it into two lines:
                  >
                  > C operator+ (C const & lhs, C const & rhs) {
                  > C result(lhs);
                  > result += rhs;
                  > return result;
                  > }
                  >
                  > Operator += returns a reference to result, which is then returned as n
                  > object (not a reference), so I guess a copy must be made there (skipping
                  > over possible optimizations, of course). So I guess it's ok, but it
                  > just looks ugly to me, and performs multiple actions on one line
                  > (calling the operator and then returning a copy of that result),
                  > something I'm loathe to do.
                  >
                  > -Howard[/color]

                  It is all legal as you described. Actually I thought at least three times
                  before posting that code. I would have written what you suggested if I
                  thought just one more time :)

                  Ali

                  Comment

                  • Arijit

                    #10
                    Re: grr... this old nut

                    Peter van Merkerk <merkerk@deadsp am.com> wrote in message news:<2libnjFd0 9cuU1@uni-berlin.de>...[color=blue]
                    > grahamo wrote:
                    >
                    > <snip>
                    >
                    > class employee
                    > {
                    > public:
                    > employee operator+(const employee& e2)
                    > {
                    > // Return the sum of *this and e2...
                    > }
                    > };
                    >
                    > You could also declare the operator+() function outside the scope of the
                    > employee class. In that case you do need two employee arguments. Since
                    > only friends can touch your employee's private parts, you may have to
                    > make operator+(const employee& e1, const employee& e2) a friend of employee:
                    >
                    > class employee
                    > {
                    > // Only needed if operator+() needs to have access to employees
                    > // privates.
                    > friend employee operator+(const employee& e1, const employee& e2);
                    >
                    > // ...other stuff...
                    >
                    > };
                    >
                    > employee operator+(const employee& e1, const employee& e2)
                    > {
                    > // Return the sum of e1 and e2...
                    > }
                    >
                    > Anyway, defining an operator+() for employees seems to be an excellent
                    > example of inappropriate use of operator overloading. To me it is not
                    > obvious what happens if you add two employees. Does it mean that e1 and
                    > e2 have intercourse and produce another employee... in that case the
                    > multiplication operator would be more appropriate ;-)[/color]


                    Shouldn't operator+ return a const object ? I mean

                    const employee operator+(const employee& e1, const employee& e2)
                    {
                    ......
                    }

                    Otherwise you can write

                    employee e1,e2,e3;
                    (e1+e2) = e3;

                    -Arijit

                    Comment

                    • Peter van Merkerk

                      #11
                      Re: grr... this old nut

                      Arijit wrote:
                      [color=blue]
                      > Shouldn't operator+ return a const object ? I mean
                      >
                      > const employee operator+(const employee& e1, const employee& e2)
                      > {
                      > .....
                      > }
                      >
                      > Otherwise you can write
                      >
                      > employee e1,e2,e3;
                      > (e1+e2) = e3;[/color]

                      I see your point. But even the standard library (e.g. std::string)
                      doesn't do this, so I guess I'm in good company ;-)

                      Could someone explain why the standard library does not return const
                      objects with operator+()?

                      --
                      Peter van Merkerk
                      peter.van.merke rk(at)dse.nl

                      Comment

                      • JKop

                        #12
                        Re: grr... this old nut

                        [color=blue]
                        > Could someone explain why the standard library does not[/color]
                        return const[color=blue]
                        > objects with operator+()?
                        >[/color]

                        It's redundant.


                        Take the following:

                        int GetNumber();

                        int main()
                        {
                        const int& p = GetNumber();
                        }

                        int GetNumber()
                        {
                        int k = 42;

                        --k;

                        k /= 2;

                        k = 6 / k;

                        return k;
                        }


                        See how I bound the return value to a const reference, I
                        had no choice in the matter. What's returned from that
                        function, and from your operator+, is a "temporary" .

                        What's a temporary? It's a const object that goes out of
                        scope at the next semicolon. So take the following:

                        void Blah(const int&);

                        int main()
                        {
                        int p = 42;

                        Blah(p + 7);
                        }


                        What gets passed to Blah? A temporary, it only exists for
                        as long as it has to, and it can't be edited, it's const.
                        This particular temporary is destroyed immediately at the
                        next semicolon, ASAP.


                        So... return values. They come in two forms:

                        Type A)

                        int Blah();
                        int* Glah();

                        Here, what's being returned is just a temporary. A
                        temporary is const, so sticking const in there would be
                        like calling out "Forename Surname" to your own sister, ie.
                        it's redundant.


                        Type B)

                        int& Blah();

                        Here, what's being returned is an actual reference to an
                        object. Here, specifying const will actually make a
                        difference:

                        int& AA();
                        const int& BB();

                        int main()
                        {
                        AA() = 5;

                        BB() = 6; //Compile ERROR
                        }


                        Anyway, without ranting-on too much, all that's being
                        returned form your Type A functions is a simple temporary,
                        they're automatically const, so you don't have to specify
                        it, you don't have a choice either way.

                        And remember, it's just a temporary!

                        -JKop

                        Comment

                        • John Harrison

                          #13
                          Re: grr... this old nut

                          On Wed, 14 Jul 2004 22:22:29 GMT, JKop <NULL@NULL.NULL > wrote:
                          [color=blue]
                          > Here, what's being returned is just a temporary. A
                          > temporary is const, so sticking const in there would be
                          > like calling out "Forename Surname" to your own sister, ie.
                          > it's redundant.
                          >[/color]

                          Not that myth again. A temporary is not const, here is the proof

                          class X
                          {
                          public:
                          void a_non_const_met hod()
                          {
                          x = 1;
                          }
                          private:
                          int x;
                          };

                          X func()
                          {
                          X
                          return x;
                          }

                          int main()
                          {
                          func().a_non_co nst_method();
                          }

                          The correct rule is that a temporary may not be bound to a noo-const
                          reference, which isn't the same thing at all.

                          john

                          Comment

                          • DaKoadMunky

                            #14
                            Re: grr... this old nut

                            >Shouldn't operator+ return a const object ? I mean[color=blue]
                            >
                            >const employee operator+(const employee& e1, const employee& e2)
                            >{
                            >.....
                            >}
                            >
                            >Otherwise you can write
                            >
                            >employee e1,e2,e3;
                            >(e1+e2) = e3;[/color]

                            I have never understood why a return value that is of class type is modifiable
                            when a return value that is of primitive type is not modifiable.

                            <CODE>

                            #include <string>
                            using std::string;

                            string ReturnClassType ()
                            {
                            return "";
                            }

                            int ReturnPrimitive Type()
                            {
                            return 0;
                            }

                            int main()
                            {
                            //This is okay!
                            ReturnClassType () = "";

                            //This is not okay!
                            ReturnPrimitive Type() = 0;

                            return 0;
                            }

                            </CODE>

                            This seems like an inconsistency to me. Both functions return temporary
                            objects yet one temporary is modifiable and the other temporary is not.

                            It seems as though one is an l-value and the other is not.

                            Can anyone help me to understand this?

                            This was actually discussed months ago and I did not grok the replies I
                            received. I will look at them again. Until then if anyone can steer me in the
                            right direction I would appreciate it.








                            Comment

                            • JKop

                              #15
                              Re: grr... this old nut

                              [color=blue]
                              > Can anyone help me to understand this?[/color]


                              Sure I can, you ain't got a C++ compiler there.

                              Get yourself a "C++ compiler" and compile it (or attempt to
                              do so), and then all will become clear.


                              -JKop

                              Comment

                              Working...