Search code examples
c++operator-overloadingforward-declaration

What's the correct in templated class forward function declaration, operator> overloading


I'm trying to overload an operator in a class and don't know the correct syntax for in class forward declarative functions, like operator.

operators

    template <typename S, typename T, typename R>
    class TRIPLE
       {
          public:
                   TRIPLE(S, T, R);
                   const TRIPLE &operator=(const TRIPLE &other); // ok
                   TRIPLE friend bool &operator> (const TRIPLE &t1, const TRIPLE &t2); // not ok
    
                   S getFirst();
                   T getSecond();
    
                   void setFirst(S);
                   void setSecond(T);
    
          private:
                   S *first;
                   T *second;
                   R *third;
       };
    
    template <typename S, typename T, typename R>
    TRIPLE<S, T, R>::TRIPLE(S x, T y, R z) : first(x), second(y), third(z) {};
    
    template <typename S, typename T, typename R>
const TRIPLE<S, T, R> &TRIPLE<S, T, R>::operator=(const TRIPLE<S, T, R> &other){
    // all good.
}
    
    template <typename S, typename T, typename R>
const TRIPLE<S, T, R> &TRIPLE<S, T, R>::operator>(TRIPLE<S, T, R> &lhs, TRIPLE<S, T, R> &rhs){
    // error: overloaded 'operator>' must be a binary operator (has 3 parameters)
}

i tried various things:

TRIPLE friend bool &operator> (const TRIPLE &t1, const TRIPLE &t2);
const TRIPLE  bool &operator> (const TRIPLE &t1, const TRIPLE &t2);
const TRIPLE friend bool &operator> (const TRIPLE &t1, const TRIPLE &t2);

edit:

bool operator>(const TRIPLE &right) const;

no errors, but ...

template <typename S, typename T, typename R>
bool operator>(TRIPLE<S, T, R> &rhs){
    return rhs; // just for test
}

error: overloaded 'operator>' must be a binary operator (has 1 parameter)


Solution

  • You have to distinguish between member and non-member operators.

    Member operator > takes one argument (operands are *this and right):

    bool TRIPLE::operator>(const TRIPLE& right) const;
    

    Non-member operator > takes two arguments (operands are left and right):

    bool operator>(const TRIPLE& left, const TRIPLE& right);
    

    By convention, binary operators that use both their operands in the same way (eg. +, -, >, < ... - in contrast to +=, -= ...) are non-member functions.

    Furthermore, you overuse TRIPLE in places where it does not make sense. I believe you got confused by the fact that the canonical form of assignment operator is TRIPLE& operator=(const TRIPLE&). That TRIPLE& at the begining is not some magic way to identify an operator, it is actually its return value (your compiler is also going to complain if you don't include return *this; at its very and)

    Lastly, you almost definitely want to be returning bool from the operators, not bool&. The latter, if it does not cause undefined behavior (dangling reference), is not an intuitive use of the operator, which kind of kills the purpose of operator overloading.