3

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

L. F.
  • 19,445
  • 8
  • 48
  • 82
Hunali
  • 277
  • 1
  • 11
  • If you place the definition inside a class you don’t need to tell the compiler which class it belongs to. If you define it outside the class the compiler has no clue unless you tell it explicitly via `T::`. – Darklighter Sep 19 '19 at 12:24
  • Are you asking when do you need to do `T::name_of_member_function`? – NathanOliver Sep 19 '19 at 12:24
  • "operator +=" is just a funky name. In declarations and definitions, it works exactly like any other function. – molbdnilo Sep 19 '19 at 12:25
  • @NathanOliver T::operator += – Hunali Sep 19 '19 at 12:25
  • Can you provide a [mre]? – L. F. Sep 19 '19 at 12:27
  • [Operator overloading](https://en.cppreference.com/w/cpp/language/operators) can be done by means of member or non-member functions. When you do it through a member function then, like with any other member function, if its definition is not within the class declaration, you need to use `T::` before its name. When you do it through a non-member function then, like with any other non-member function, you don't need to prefix its with anything. – jdehesa Sep 19 '19 at 12:41

2 Answers2

2

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.

L. F.
  • 19,445
  • 8
  • 48
  • 82
  • I was reading the documentation of the operators. So I was confused thank you for you're the explanation it helped me a lot! One more thing should I use T with a reference like this T&operaotr or just T operator? – Hunali Sep 19 '19 at 12:55
  • 1
    @Hunali Usually compound assignment operators like += or -= return a reference to `*this`. – L. F. Sep 19 '19 at 13:01
2

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';
}    
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335