Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between inner and outer overloaded C++ operator

I have the following code that will not compile, complaining that += operator does not exist. += operator is here declared outside of class A.

template < typename _T >
class A {
public:
    operator _T () const { return 42 ; }
};

template <typename _T >
A< _T > & operator += ( A< _T > & l, _T r ) { return l ; }


int main() {
    A< int > e, f ;
    e += f ;
    return 0 ;
}

However, if I implement the operator inside class A, code compiles and works :

template < typename _T >
class A {
public:
    operator _T () const { return 42 ; }

    A< _T > & operator += ( _T r ) { return *this ; }
};


int main() {
    A< int > e, f ;
    e += f ;
    return 0 ;
}

What is the difference between these two codes? Aren't they supposed to be equivalent?

This was compiled with gcc 4.4.7-4.

like image 455
Hugus Avatar asked Dec 20 '16 16:12

Hugus


People also ask

Which operator can be overloaded in C?

Operator Overloading in C++ Overloaded operator is used to perform operation on user-defined data type. For example '+' operator can be overloaded to perform addition on various data types, like for Integer, String(concatenation) etc.

Which operator can overloaded in c plus plus?

This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.

Can& be overloaded in C++?

Most can be overloaded. The only C operators that can't be are . and ?: (and sizeof , which is technically an operator). C++ adds a few of its own operators, most of which can be overloaded except :: and .


1 Answers

The first example fails to compile because template argument deduction does not do any conversion. With

template <typename _T >
A< _T > & operator += ( A< _T > & l, _T r ) { return l ; }

Both l and r contribute to determining what _T is. When you do e += f then the compiler gets that _T must be int for l and it gets r must be A<int> since that is the type of f. Since they do not match it fails to compile.

In the second code there is no template argument deduction going on. The compiler knows what _T is from the instantiation of the class so all it needs to be able to do is convert what is passed to r to a _T.


I also suggest you get out of the habit of starting names with underscores. There are a slew of rules about them and if you violate them then your program has undefined behavior since they are reserved for the implementation. For more see What are the rules about using an underscore in a C++ identifier?

like image 129
NathanOliver Avatar answered Sep 19 '22 08:09

NathanOliver