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.
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.
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 +.
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 .
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With