ambiguous overload

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

    ambiguous overload

    #include<iostre am>
    using namespace std;
    class Integer{
    int i;
    public:
    Integer(int ii):i(ii){}
    const Integer operator+(const Integer& rv){
    cout<<"1-operator+"<<end l;
    return Integer(i+rv.i) ;
    }
    Integer operator+=(Inte ger rv){
    i+=rv.i;
    cout<<"2-operator+="<<en dl;
    return *this;
    }
    friend Integer& operator+(Integ er,Integer);

    void display(){
    cout<<"3-display()// i="<<i<<endl;
    }
    };
    Integer& operator+(Integ er rv,Integer rs ){
    cout<<"2-operator+="<<en dl;
    rv.i+=rs.i;
    return rv;
    }
    int main(void){
    cout<<"buit-in types"<<endl;
    int i=1,j=2,k=3;
    k+=i+j;
    cout<<"user defined types:"<<endl;
    Integer ii(1),jj(2),kk( 3);
    kk+=ii+jj;
    Integer d(1),b(2);
    d=2+b;
    d.display();
    return 0;
    }




    g++ -g -Wall -o test test.cpp
    test.cpp: In function 'Integer& operator+(Integ er, Integer)':
    test.cpp:22: warning: reference to local variable 'rv' returned
    test.cpp: In function 'int main()':
    test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
    test.cpp:7: note: candidates are: const Integer Integer::operat or+
    (const Integer&)
    test.cpp:22: note: Integer& operator+(Integ er,
    Integer)
    make: *** [test] Error 1
    ??

    What should I do to prevent this ??
  • Ian Collins

    #2
    Re: ambiguous overload

    onkar wrote:
    #include<iostre am>
    using namespace std;
    class Integer{
    int i;
    public:
    Integer(int ii):i(ii){}
    const Integer operator+(const Integer& rv){
    cout<<"1-operator+"<<end l;
    return Integer(i+rv.i) ;
    }
    Integer operator+=(Inte ger rv){
    i+=rv.i;
    cout<<"2-operator+="<<en dl;
    return *this;
    }
    friend Integer& operator+(Integ er,Integer);
    >
    void display(){
    cout<<"3-display()// i="<<i<<endl;
    }
    };
    Integer& operator+(Integ er rv,Integer rs ){
    cout<<"2-operator+="<<en dl;
    rv.i+=rs.i;
    return rv;
    You shouldn't return a reference to a local variable!
    What should I do to prevent this ??
    Stick to one operator+. Why have two?

    --
    Ian Collins.

    Comment

    • onkar

      #3
      Re: ambiguous overload

      On Jan 7, 11:02 am, Ian Collins <ian-n...@hotmail.co mwrote:
      onkar wrote:
      #include<iostre am>
      using namespace std;
      class Integer{
      int i;
      public:
      Integer(int ii):i(ii){}
      const Integer operator+(const Integer& rv){
      cout<<"1-operator+"<<end l;
      return Integer(i+rv.i) ;
      }
      Integer operator+=(Inte ger rv){
      i+=rv.i;
      cout<<"2-operator+="<<en dl;
      return *this;
      }
      friend Integer& operator+(Integ er,Integer);
      >
      void display(){
      cout<<"3-display()// i="<<i<<endl;
      }
      };
      Integer& operator+(Integ er rv,Integer rs ){
      cout<<"2-operator+="<<en dl;
      rv.i+=rs.i;
      return rv;
      >
      You shouldn't return a reference to a local variable!
      >
      What should I do to prevent this ??
      >
      Stick to one operator+. Why have two?
      >
      --
      Ian Collins.
      #include<iostre am>
      using namespace std;
      class Integer{
      int i;
      public:
      Integer(int ii):i(ii){}
      /* const Integer operator+(const Integer& rv){
      cout<<"1-operator+"<<end l;
      return Integer(i+rv.i) ;
      } */
      Integer operator+=(Inte ger rv){
      i+=rv.i;
      cout<<"2-operator+="<<en dl;
      return *this;
      }
      friend Integer& operator+(Integ er,Integer);

      void display(){
      cout<<"3-display()// i="<<i<<endl;
      }
      };
      Integer& operator+(Integ er rv,Integer rs ){
      cout<<"4-operator+"<<end l;
      rv.i+=rs.i;
      return rv;
      }
      int main(void){
      cout<<"buit-in types"<<endl;
      int i=1,j=2,k=3;
      k+=i+j;
      cout<<"user defined types:"<<endl;
      Integer ii(1),jj(2),kk( 3);
      kk+=ii+jj;
      Integer d(1),b(2);
      d=2+b;
      d.display();
      return 0;
      }



      How to prevent this warning ??


      g++ -g -Wall -o test test.cpp
      test.cpp: In function 'Integer& operator+(Integ er, Integer)':
      test.cpp:22: warning: reference to local variable 'rv' returned

      Note: If I remove & in
      Integer& operator+(Integ er rv,Integer rs )

      g++ -g -Wall -o test test.cpp
      test.cpp: In function 'Integer operator+(Integ er, Integer)':
      test.cpp:22: error: new declaration 'Integer operator+(Integ er,
      Integer)'
      test.cpp:16: error: ambiguates old declaration 'Integer& operator+
      (Integer, Integer)'
      make: *** [test] Error 1

      ?? deadlocklike situation ?? :(

      Comment

      • Ian Collins

        #4
        Re: ambiguous overload

        onkar wrote:
        On Jan 7, 11:02 am, Ian Collins <ian-n...@hotmail.co mwrote:
        >onkar wrote:
        >>Integer& operator+(Integ er rv,Integer rs ){
        >> cout<<"2-operator+="<<en dl;
        >> rv.i+=rs.i;
        >> return rv;
        >You shouldn't return a reference to a local variable!
        >>
        >>What should I do to prevent this ??
        >Stick to one operator+. Why have two?
        >>
        *Don't* quote signatures.
        >
        How to prevent this warning ??
        >
        I told you last time.

        --
        Ian Collins.

        Comment

        • Jerry Coffin

          #5
          Re: ambiguous overload

          In article <a21174f2-a51d-43e0-ae68-ac11ab654101
          @e23g2000prf.go oglegroups.com> , onkar.n.m@gmail .com says...

          [ ... ]
          Integer& operator+(Integ er rv,Integer rs ){
          cout<<"4-operator+"<<end l;
          rv.i+=rs.i;
          return rv;
          }
          You're still returning a reference to a local variable. As much as you'd
          like to return a reference to some existing variable, you really can't
          -- you need to create and return a new instance. OTOH, you can pass one
          of the parameters by reference (to const).

          [ ... ]
          Note: If I remove & in
          Integer& operator+(Integ er rv,Integer rs )
          >
          g++ -g -Wall -o test test.cpp
          test.cpp: In function 'Integer operator+(Integ er, Integer)':
          test.cpp:22: error: new declaration 'Integer operator+(Integ er,
          Integer)'
          test.cpp:16: error: ambiguates old declaration 'Integer& operator+
          (Integer, Integer)'
          The compiler is just telling you that this function body no longer
          matches your friend declaration above, and the two (if there really were
          two) would be ambiguous. You just need to make the friend declaration
          and the function definition match each other. One way to do that is to
          put them together:

          class Integer {
          // ...

          friend Integer operator+(Integ er rv, Integer rs) {
          rv.i+=rs.i;
          return rv;
          }
          };

          Even though we've placed the body of the operator+ inside of the class
          defintion, it is still a _global_ function, visible outside the class,
          just as if its defintion were outside the class like you wrote it. FWIW,
          this code is definitely open to further optimization (it creates at
          least one more Integer object than necessary).

          --
          Later,
          Jerry.

          The universe is a figment of its own imagination.

          Comment

          • Salt_Peter

            #6
            Re: ambiguous overload

            On Jan 7, 1:07 am, onkar <onkar....@gmai l.comwrote:
            <snip>
            onkar wrote:
            How to prevent this warning ??
            >
            g++ -g -Wall -o test test.cpp
            test.cpp: In function 'Integer& operator+(Integ er, Integer)':
            test.cpp:22: warning: reference to local variable 'rv' returned
            To prevent the warning, listen to the compiler. Acknowledge that rv, a
            local variable, is destroyed once the function returns. You'll end up
            with an invalid reference. One doesn't mail a letter to an address
            that is about to cease to exist. Sounds silly because it is silly.

            According to the statements you are showing in main(),
            a) the only friend op i see would be:

            friend Integer operator+(const int, const Integer&);

            b) and a member function to add a primitive integer:

            Integer& Integer::operat or+(const int n)
            {
            ...
            }

            Comment

            • asterisc

              #7
              Re: ambiguous overload

              On Jan 7, 7:43 am, onkar <onkar....@gmai l.comwrote:
              #include<iostre am>
              using namespace std;
              class Integer{
              int i;
              public:
              Integer(int ii):i(ii){}
              const Integer operator+(const Integer& rv){
              cout<<"1-operator+"<<end l;
              return Integer(i+rv.i) ;
              }
              Integer operator+=(Inte ger rv){
              i+=rv.i;
              cout<<"2-operator+="<<en dl;
              return *this;
              }
              friend Integer& operator+(Integ er,Integer);
              >
              void display(){
              cout<<"3-display()// i="<<i<<endl;
              }};
              >
              Integer& operator+(Integ er rv,Integer rs ){
              cout<<"2-operator+="<<en dl;
              rv.i+=rs.i;
              return rv;}
              >
              int main(void){
              cout<<"buit-in types"<<endl;
              int i=1,j=2,k=3;
              k+=i+j;
              cout<<"user defined types:"<<endl;
              Integer ii(1),jj(2),kk( 3);
              kk+=ii+jj;
              Integer d(1),b(2);
              d=2+b;
              d.display();
              return 0;
              >
              }
              >
              g++ -g -Wall -o test test.cpp
              test.cpp: In function 'Integer& operator+(Integ er, Integer)':
              test.cpp:22: warning: reference to local variable 'rv' returned
              test.cpp: In function 'int main()':
              test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
              test.cpp:7: note: candidates are: const Integer Integer::operat or+
              (const Integer&)
              test.cpp:22: note: Integer& operator+(Integ er,
              Integer)
              make: *** [test] Error 1
              ??
              >
              What should I do to prevent this ??
              For classes like the one designed by you, often is a good idea to
              overload a conversion operator like "operator int();".
              That way, you don't need to overload all the needed arithmetic
              operators, relational operators, ...

              Comment

              • siddhu

                #8
                Re: ambiguous overload

                On Jan 7, 8:35 am, asterisc <Rares....@ni.c omwrote:
                On Jan 7, 7:43 am, onkar <onkar....@gmai l.comwrote:
                >
                >
                >
                >
                >
                #include<iostre am>
                using namespace std;
                class Integer{
                        int i;
                        public:
                                Integer(int ii):i(ii){}
                                const Integer operator+(const Integer& rv){
                                        cout<<"1-operator+"<<end l;
                                        return Integer(i+rv.i) ;
                                }
                                Integer operator+=(Inte ger rv){
                                        i+=rv.i;
                                        cout<<"2-operator+="<<en dl;
                                        return *this;
                                }
                                friend Integer& operator+(Integ er,Integer);
                >
                                void display(){
                                        cout<<"3-display()// i="<<i<<endl;
                                }};
                >
                Integer& operator+(Integ er rv,Integer rs ){
                                        cout<<"2-operator+="<<en dl;
                        rv.i+=rs.i;
                        return rv;}
                >
                int main(void){
                         cout<<"buit-in types"<<endl;
                        int i=1,j=2,k=3;
                        k+=i+j;
                        cout<<"user defined types:"<<endl;
                        Integer ii(1),jj(2),kk( 3);
                        kk+=ii+jj;
                        Integer d(1),b(2);
                        d=2+b;
                        d.display();
                        return 0;
                >
                }
                >
                g++ -g -Wall -o test test.cpp
                test.cpp: In function 'Integer& operator+(Integ er, Integer)':
                test.cpp:22: warning: reference to local variable 'rv' returned
                test.cpp: In function 'int main()':
                test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
                test.cpp:7: note: candidates are: const Integer Integer::operat or+
                (const Integer&)
                test.cpp:22: note:                 Integer& operator+(Integ er,
                Integer)
                make: *** [test] Error 1
                ??
                >
                What should I do to prevent this ??
                >
                For classes like the one designed by you, often is a good idea to
                overload a conversion operator like "operator int();".
                That way, you don't need to overload all the needed arithmetic
                operators, relational operators, ...- Hide quoted text -
                >
                - Show quoted text -
                Better way to have only a friend operator+ function. Do not have
                member fn. This way you can also do calcultions like
                Integer I(1);
                Integer J = 1 + I;

                operator+ can be implemented in terms of operator+=. e.g.

                friend const Integer(const Integer& I1,const Integer& I2)
                {
                Integer temp(I1);
                temp += I2;
                return temp;
                }

                Comment

                • Victor Bazarov

                  #9
                  Re: ambiguous overload

                  siddhu wrote:
                  On Jan 7, 8:35 am, asterisc <Rares....@ni.c omwrote:
                  >On Jan 7, 7:43 am, onkar <onkar....@gmai l.comwrote:
                  >>
                  >>
                  >>
                  >>
                  >>
                  >>#include<iost ream>
                  >>using namespace std;
                  >>class Integer{
                  >>int i;
                  >>public:
                  >>Integer(int ii):i(ii){}
                  >>const Integer operator+(const Integer& rv){
                  >>cout<<"1-operator+"<<end l;
                  >>return Integer(i+rv.i) ;
                  >>}
                  >>Integer operator+=(Inte ger rv){
                  >>i+=rv.i;
                  >>cout<<"2-operator+="<<en dl;
                  >>return *this;
                  >>}
                  >>friend Integer& operator+(Integ er,Integer);
                  >>
                  >>void display(){
                  >>cout<<"3-display()// i="<<i<<endl;
                  >>}};
                  >>
                  >>Integer& operator+(Integ er rv,Integer rs ){
                  >>cout<<"2-operator+="<<en dl;
                  >>rv.i+=rs.i;
                  >>return rv;}
                  >>
                  >>int main(void){
                  >>cout<<"buit-in types"<<endl;
                  >>int i=1,j=2,k=3;
                  >>k+=i+j;
                  >>cout<<"user defined types:"<<endl;
                  >>Integer ii(1),jj(2),kk( 3);
                  >>kk+=ii+jj;
                  >>Integer d(1),b(2);
                  >>d=2+b;
                  >>d.display() ;
                  >>return 0;
                  >>
                  >>}
                  >>
                  >>g++ -g -Wall -o test test.cpp
                  >>test.cpp: In function 'Integer& operator+(Integ er, Integer)':
                  >>test.cpp:22 : warning: reference to local variable 'rv' returned
                  >>test.cpp: In function 'int main()':
                  >>test.cpp:33 : error: ambiguous overload for 'operator+' in 'ii + jj'
                  >>test.cpp:7: note: candidates are: const Integer Integer::operat or+
                  >>(const Integer&)
                  >>test.cpp:22 : note: Integer& operator+(Integ er,
                  >>Integer)
                  >>make: *** [test] Error 1
                  >>??
                  >>
                  >>What should I do to prevent this ??
                  >>
                  >For classes like the one designed by you, often is a good idea to
                  >overload a conversion operator like "operator int();".
                  >That way, you don't need to overload all the needed arithmetic
                  >operators, relational operators, ...- Hide quoted text -
                  >>
                  >- Show quoted text -
                  >
                  Better way to have only a friend operator+ function. Do not have
                  member fn. This way you can also do calcultions like
                  Integer I(1);
                  Integer J = 1 + I;
                  >
                  operator+ can be implemented in terms of operator+=. e.g.
                  >
                  friend const Integer(const Integer& I1,const Integer& I2)
                  Probably meant to define it as

                  friend const Integer operator+(const Integer ....

                  although I am not sure why you want it to return a 'const'.
                  {
                  Integer temp(I1);
                  temp += I2;
                  return temp;
                  }
                  And the body could simply look like this

                  {
                  return Integer(I1.i + I2.i);
                  }

                  There is really no need to implement it in terms of +=, is there?

                  V
                  --
                  Please remove capital 'A's when replying by e-mail
                  I do not respond to top-posted replies, please don't ask


                  Comment

                  • James Kanze

                    #10
                    Re: ambiguous overload

                    On Jan 7, 7:07 am, onkar <onkar....@gmai l.comwrote:
                    #include<iostre am>
                    using namespace std;
                    class Integer{
                    int i;
                    public:
                    Integer(int ii):i(ii){}
                    /* const Integer operator+(const Integer& rv){
                    cout<<"1-operator+"<<end l;
                    return Integer(i+rv.i) ;
                    } */
                    Integer operator+=(Inte ger rv){
                    i+=rv.i;
                    cout<<"2-operator+="<<en dl;
                    return *this;
                    }
                    friend Integer& operator+(Integ er,Integer);
                    >
                    void display(){
                    cout<<"3-display()// i="<<i<<endl;
                    }};
                    Integer& operator+(Integ er rv,Integer rs ){
                    cout<<"4-operator+"<<end l;
                    rv.i+=rs.i;
                    return rv;}
                    int main(void){
                    cout<<"buit-in types"<<endl;
                    int i=1,j=2,k=3;
                    k+=i+j;
                    cout<<"user defined types:"<<endl;
                    Integer ii(1),jj(2),kk( 3);
                    kk+=ii+jj;
                    Integer d(1),b(2);
                    d=2+b;
                    d.display();
                    return 0;
                    }
                    How to prevent this warning ??
                    g++ -g -Wall -o test test.cpp
                    test.cpp: In function 'Integer& operator+(Integ er, Integer)':
                    test.cpp:22: warning: reference to local variable 'rv' returned
                    Read the text of the warning. It's quite clear. The obvious
                    way to avoid a warning "reference to local variable 'rv'
                    returned" is to not return a reference to the local variable
                    'rv', no?

                    In general, you shouldn't ever return a reference to a local
                    variable, since there's no way the client can use that reference
                    without incurring undefined behavior.
                    Note: If I remove & in
                    Integer& operator+(Integ er rv,Integer rs )
                    g++ -g -Wall -o test test.cpp
                    test.cpp: In function 'Integer operator+(Integ er, Integer)':
                    test.cpp:22: error: new declaration 'Integer operator+(Integ er,
                    Integer)'
                    test.cpp:16: error: ambiguates old declaration 'Integer& operator+
                    (Integer, Integer)'
                    make: *** [test] Error 1
                    Of course. All of the declarations have to be identical. If
                    you remove it in one declaration, you have to remove it in all.

                    --
                    James Kanze (GABI Software) email:james.kan ze@gmail.com
                    Conseils en informatique orientée objet/
                    Beratung in objektorientier ter Datenverarbeitu ng
                    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                    Comment

                    • James Kanze

                      #11
                      Re: ambiguous overload

                      On Jan 7, 2:35 pm, asterisc <Rares....@ni.c omwrote:
                      On Jan 7, 7:43 am, onkar <onkar....@gmai l.comwrote:
                      >
                      >
                      >
                      #include<iostre am>
                      using namespace std;
                      class Integer{
                      int i;
                      public:
                      Integer(int ii):i(ii){}
                      const Integer operator+(const Integer& rv){
                      cout<<"1-operator+"<<end l;
                      return Integer(i+rv.i) ;
                      }
                      Integer operator+=(Inte ger rv){
                      i+=rv.i;
                      cout<<"2-operator+="<<en dl;
                      return *this;
                      }
                      friend Integer& operator+(Integ er,Integer);
                      >
                      void display(){
                      cout<<"3-display()// i="<<i<<endl;
                      }};
                      >
                      Integer& operator+(Integ er rv,Integer rs ){
                      cout<<"2-operator+="<<en dl;
                      rv.i+=rs.i;
                      return rv;}
                      >
                      int main(void){
                      cout<<"buit-in types"<<endl;
                      int i=1,j=2,k=3;
                      k+=i+j;
                      cout<<"user defined types:"<<endl;
                      Integer ii(1),jj(2),kk( 3);
                      kk+=ii+jj;
                      Integer d(1),b(2);
                      d=2+b;
                      d.display();
                      return 0;
                      >
                      }
                      >
                      g++ -g -Wall -o test test.cpp
                      test.cpp: In function 'Integer& operator+(Integ er, Integer)':
                      test.cpp:22: warning: reference to local variable 'rv' returned
                      test.cpp: In function 'int main()':
                      test.cpp:33: error: ambiguous overload for 'operator+' in 'ii + jj'
                      test.cpp:7: note: candidates are: const Integer Integer::operat or+
                      (const Integer&)
                      test.cpp:22: note: Integer& operator+(Integ er,
                      Integer)
                      make: *** [test] Error 1
                      ??
                      >
                      What should I do to prevent this ??
                      >
                      For classes like the one designed by you, often is a good idea to
                      overload a conversion operator like "operator int();".
                      That way, you don't need to overload all the needed arithmetic
                      operators, relational operators, ...

                      Comment

                      • James Kanze

                        #12
                        Re: ambiguous overload

                        On Jan 7, 5:51 pm, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
                        siddhu wrote:
                        [...]
                        Better way to have only a friend operator+ function. Do not have
                        member fn. This way you can also do calcultions like
                        Integer I(1);
                        Integer J = 1 + I;
                        operator+ can be implemented in terms of operator+=. e.g.
                        friend const Integer(const Integer& I1,const Integer& I2)
                        Probably meant to define it as
                        friend const Integer operator+(const Integer ....
                        although I am not sure why you want it to return a 'const'.
                        To prevent things like:
                        Integer i, j, k ;
                        (i + j) = k ;
                        I've read (in Scott Meyers, I think) that this is a good idea.
                        Abstractly, I think it's a good idea. In practice, I've never
                        bothered; the type of error it prevents doesn't seem to occur in
                        practice anyway.
                        {
                        Integer temp(I1);
                        temp += I2;
                        return temp;
                        }
                        And the body could simply look like this
                        {
                        return Integer(I1.i + I2.i);
                        }
                        There is really no need to implement it in terms of +=, is there?
                        In such a simple case as this, no. It's the idiomatic solution,
                        however---normally, if you're doing much of this sort of thing,
                        you'll actually defined such operations in a templated base
                        class, so all you have to do is derive, e.g.:

                        template< typename T >
                        class ArithmeticOpera tors
                        {
                        friend T operator+( T const& lhs, T const& rhs )
                        {
                        T result( lhs ) ;
                        result += rhs ;
                        return result ;
                        }
                        // The same for all of the arithmeitc operators...
                        } ;

                        class BigInteger : private ArithmeticOpera tors< BigInteger >
                        {
                        public :
                        // ...
                        BigInteger& operator+=( BigInteger const& other ) ;
                        // ...
                        } ;

                        It saves a lot of typing, and positively guarantees that + will
                        have the same semantics as +=. (And if you've misunderstood the
                        requirements, and implemented the wrong semantics, you only have
                        to change the code at one place.)

                        --
                        James Kanze (GABI Software) email:james.kan ze@gmail.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        Working...