Search code examples
c++oopoperator-overloadingscope-resolution-operator

Scope operator in Operator Overloading


I'm not able to understand the scope operator in Operator overloading. There are examples when they are using it when they don't. When I'm supposed to write T::operator. Can I write just the operator still works fine or is it recommended to use::?

The example:


Prototype examples (for class T) Inside class definition

T& T::operator +=(const T2& b){}

Can I write it like T& operator +=(const T2& b){} Or should I always write it like T& T::operator +=(const T2& b){}


Solution

  • The operator += may be declared as a member function or member template of a class or class template and defined either within the class or class template or outside them.

    If it is defined outside the class then the scope operator is required.

    The operator may be also declared and defined as a stand-alone non-class function

    Consider the following demonstrative program

    #include <iostream>
    
    struct A
    {
        int x = 0;
    
        A & operator +=( char c )
        {
            x += c;
            return *this;
        }
    };
    
    struct B
    {
        int x = 0;
    
        B & operator +=( char c );
    };
    
    B & B::operator +=( char c )
    {
        x += c;
        return *this;
    }
    
    struct C
    {
        int x = 0;
    };
    
    C & operator +=( C & cls, char c )
    {
        cls.x += c;
    
        return cls;
    }
    
    int main() 
    {
        A a;
    
        a += 'A';
    
        std::cout << "a.x = " << a.x << '\n';
    
        B b;
    
        b += 'B';
    
        std::cout << "b.x = " << b.x << '\n';
    
        C c;
    
        c += 'C';
    
        std::cout << "c.x = " << c.x << '\n';
    
        return 0;
    }
    

    Its output is

    a.x = 65
    b.x = 66
    c.x = 67
    

    The operator can be also declared as a template operator. For example

    #include <iostream>
    
    template <class T>
    struct A
    {
        T x = T();
    };    
    
    template <class T1, class T2>
    T1 & operator +=( T1 &a, const T2 &x ) /* C++ 17 only requires requires( T1 t ) { t.x; }*/  
    {
        a.x += x;
        return a;
    }        
    
    int main()
    {
    
        A<int> a;
        std::cout << ( a += 10u ).x << '\n';
    }    
    

    Again if the operator is a member function template and is defined outside its class then the scope resolution operator is required.

    #include <iostream>
    
    template <class T1>
    struct A
    {
        T1 x = T1();
        template <class T2>
        A<T1> & operator +=( const T2 &x );
    };    
    
    template <class T1>
    template <class T2>
    A<T1> & A<T1>::operator +=( const T2 &x )
    {
        this->x += x;
        return *this;
    }        
    
    int main()
    {
    
        A<int> a;
        std::cout << ( a += 10u ).x << '\n';
    }