Thread: ambiguous overload for operators...

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    7

    ambiguous overload for operators...

    i have a little problem and i cant figure it out.

    here is a piece of code:

    Code:
    ...
     
     struct razlomak {
            
            int brojnik, nazivnik;       
            
            razlomak( int br = 0, int naz = 1 ) { brojnik = br; nazivnik = naz; skratiMe(); }
            
         ...
            
            razlomak operator+( const razlomak& b ){
                     
                     razlomak vrati( brojnik*b.nazivnik + nazivnik*b.brojnik, nazivnik*b.nazivnik );
                              
                     return vrati;         
                              
            }
            
            razlomak operator-( const razlomak& b ){
                     
                    razlomak vrati( brojnik*b.nazivnik - nazivnik*b.brojnik, nazivnik*b.nazivnik ); 
                              
                    return vrati;          
                              
            }
            
            razlomak operator-(){
                 
                 razlomak vrati( -brojnik, nazivnik );
                 
                 return vrati;
                        
            }
            
            
            friend ostream& operator<<( ostream& , const razlomak& );
            friend razlomak operator+( const razlomak&, const razlomak& );
            friend razlomak operator-( int, const razlomak& );
            
            bool operator==( const razlomak& b ){
                  if( brojnik == b.brojnik && nazivnik == b.nazivnik ) return true;
                  return false;
            }
            
            bool operator<=( const razlomak& b ){
                 if( brojnik*b.nazivnik <= nazivnik*b.brojnik ) return true;
                 return false;      
            }
            
            bool operator<( const razlomak& b ){
                 if( brojnik*b.nazivnik < nazivnik*b.brojnik ) return true;
                 return false;      
            }
            
             bool operator>=( const razlomak& b ){
                 if( brojnik*b.nazivnik >= nazivnik*b.brojnik ) return true;
                 return false;      
            }
            
            bool operator>( const razlomak& b ){
                 if( brojnik*b.nazivnik > nazivnik*b.brojnik ) return true;
                 return false;      
            }
            
            bool operator!=( const razlomak& b ){
                 if( brojnik*b.nazivnik != nazivnik*b.brojnik ) return true;
                 return false;      
            }
            
            operator bool(){
                 if( brojnik != 0 ) return true;
                 return false;     
            }
            
            bool operator!(){ 
                 if( brojnik == 0 ) return true;
                 return false;     
            }
            
            friend bool operator==( int, const razlomak& );
            friend bool operator<=( int, const razlomak& );
            friend bool operator<( int, const razlomak& );
            friend bool operator>=( int, const razlomak& );
            friend bool operator>( int, const razlomak& );
            friend bool operator!=( int, const razlomak& );
            
            
     };
     
     ostream& operator<<( ostream& r, const razlomak& x ){
              r << x.brojnik << " / " << x.nazivnik;
              return r;          
     }
     
     razlomak operator-( int a, const razlomak& b ){
              
              return razlomak( a*b.nazivnik - b.brojnik, b.nazivnik );
                       
     }
     
     razlomak operator+( int, const razlomak& b ){
               return razlomak( a*b.nazivnik + b.brojnik, b.nazivnik );
              
     }
     
     bool operator==( int a, const razlomak& b ){
                 if( a == b.brojnik && b.nazivnik == 1 ) return true;
                 return false;      
     }
     
     bool operator<=( int a, const razlomak& b ){
                 if( a*b.nazivnik <= b.brojnik ) return true;
                 return false;      
     }
     
     bool operator<( int a, const razlomak& b ){
                 if( a*b.nazivnik < b.brojnik ) return true;
                 return false;      
     }
     
     bool operator>=( int a, const razlomak& b ){
                 if( a*b.nazivnik >= b.brojnik ) return true;
                 return false;      
     }
     
     bool operator>( int a, const razlomak& b ){
                 if( a*b.nazivnik > b.brojnik ) return true;
                 return false;      
     }
     
     bool operator!=( int a, const razlomak& b ){
                 if( a != b.brojnik || 1 != b.nazivnik ) return true;
                 return false;      
     }
     
     int main(){ 
         
      razlomak A( 3, 9 );
      razlomak B( 4, 16 );
      
      cout << A+B << endl; 
      cout << A+1 << endl; 
      cout << 1+A << endl;
      cout << 1-A << endl; 
     
      cin.get();
      return 0;    
         
     }
    compiler is throwing me an error for ambiguous overload of operator + in

    line:

    Code:
    cout << A+1 << endl;
    but i dont know where is the problem?
    compiler says that candidates are:
    operator+( int, int ) ??? why ?
    operator+( const razlomak& ) -> this should be ok ( after implicit conversion of 1 )
    operator+( int, const razlomak& ) ???

    and the strange thing in problem is that if i dont have all this operators of comparisons everthing works just fine ( so the problem is not in the code? ).

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    + is not automatically commutative -- defining int + razlomak gives no information whatsoever on how to do razlomak + int. The two outside versions suggest that the compiler is finding a conversion from razlomak to int (did you define an operator int() for the class?).

  3. #3
    Registered User
    Join Date
    Jan 2011
    Posts
    7
    Quote Originally Posted by tabstop View Post
    + is not automatically commutative -- defining int + razlomak gives no information whatsoever on how to do razlomak + int. The two outside versions suggest that the compiler is finding a conversion from razlomak to int (did you define an operator int() for the class?).
    razlomak + int should work because int should implicitly convert into razlomak. And that works fine without all this operators of comparison... ( just include iostream, use std, and erase using function skratiMe() in constructor, and comment all operators of comparison ), but with them it's not working...

    razlomak + int.
    int implicitly converts into razlomak ( constructor is razlomak( int=0,int=1 ) ), and than it should works with razlomak + razlomak.
    Didnt do cast to int, so that's not the reason for problem int+int
    Last edited by Cobs; 05-11-2011 at 05:41 PM.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    If you can build razlomak out of integers, you don't need to define any operators for the integer parts of the expression.

    What will happen is the int will be promoted before doing, for example
    Code:
     friend razlomak operator+( const razlomak&, const razlomak& );
    You don't need to tell C++ how to do this beyond defining a constructor that takes an int.
    Last edited by whiteflags; 05-11-2011 at 05:55 PM.

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    And if you were the computer, with the expression 1+A or A+1, can you tell me, do you call the member function:
    Code:
            razlomak operator+( const razlomak& b ){
                     
                     razlomak vrati( brojnik*b.nazivnik + nazivnik*b.brojnik, nazivnik*b.nazivnik );
                              
                     return vrati;         
                              
            }
    or the free friend function:

    Code:
            friend razlomak operator+( const razlomak&, const razlomak& );
    That is why this operator, and several operators in fact, are ambiguous.

  6. #6
    Registered User
    Join Date
    Jan 2011
    Posts
    7
    Quote Originally Posted by whiteflags View Post
    If you can build razlomak out of integers, you don't need to define any operators for the integer parts of the expression.

    What will happen is the int will be promoted before doing, for example
    Code:
     friend razlomak operator+( const razlomak&, const razlomak& );
    You don't need to tell C++ how to do this beyond defining a constructor that takes an int.
    sorry I added this line after...( tried to find solution , but forgot to wrote that line like it was in original file )
    in original file it is:
    Code:
    friend razlomak operator+( int, const razlomak& );
    still dont know why operators are ambigouous.

    in: A + 1 computer should call: operator+( const razlomak& );
    in: 1 + A computer should call: friend razlomak operator+( int, const razlomak& );
    Last edited by Cobs; 05-11-2011 at 06:10 PM.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You didn't do operator int(), but now I see operator bool() which is just as good (as far as this goes). So your razlomak's can be converted to bool, which is an int type and therefore becomes int when you do things like + with it. So A+1 could be: bool + int or razlomak + razlomak. You want the second, but the computer isn't able to read your mind and disallow the first.

  8. #8
    Registered User
    Join Date
    Jan 2011
    Posts
    7
    Thanks!!!

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Speaking of operator bool: if you are using a compiler with sufficient support for the next edition of the C++ Standard (due to be ratified this year), declare it explicit, e.g.,
    Code:
        explicit operator bool() const {
            return brojnik != 0;
        }
    Otherwise, make use of the safe bool idiom, or at least overload operator void* instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-31-2010, 08:29 PM
  2. ambiguous overload with derived classes?
    By Sebastiani in forum C++ Programming
    Replies: 2
    Last Post: 05-22-2008, 10:14 PM
  3. Overload Operators
    By verbity in forum C++ Programming
    Replies: 3
    Last Post: 03-25-2007, 11:13 AM
  4. using templates to overload operators
    By Ancient Dragon in forum C++ Programming
    Replies: 3
    Last Post: 05-24-2006, 10:18 PM
  5. ambiguous << operator, overload not right?
    By neandrake in forum C++ Programming
    Replies: 7
    Last Post: 11-14-2004, 11:18 PM