Hunali
Hunali

Reputation: 277

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){}

Upvotes: 3

Views: 1216

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

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';
}    

Upvotes: 2

L. F.
L. F.

Reputation: 20579

Inside the class, you don't use the scope resolution operator :::

class T {
public:
    // ...
    T operator+=(const T2& b)
    {
        // ...
    }
};

If you define the operator outside the class, then you use the scope resolution operator :: in the out of class definition. You still omit it in the declaration:

class T {
public:
    // ...
    T operator+=(const T2& b);
};

// in the implementation
T T::operator+=(const T2& b)
{
    // ...
}

This has nothing to do with recommendation or good practice. Everything stated here is the only way that can work, the other ways are just not correct C++ code.

Upvotes: 2

Related Questions