SomeClass sc;
int iobj = sc + 3;
#include <iostream>
struct SmallInt {
SmallInt(int val) : _val(val) { std::cout << "Called ctor\n"; }
SmallInt operator+( int a ){ std::cout << "Called SmallInt::operator+\n"; return _val+a; }
void showVal(){ std::cout << "val = " << _val << "\n"; }
int _val;
};
SmallInt operator+ ( const SmallInt& s1, const SmallInt& s2){
std::cout << "Called SmallInt::operator+\n";
return s1._val+s2._val;
}
int main() {
SmallInt s(1);
s = 1 + 2; // Calls built-int operator+(int,int)
s.showVal();
return 0;
}
#include <iostream>
class SmallInt {
public:
SmallInt(int val) : _val(val) {
std::cout << "Called ctor\n";
}
int _val;
};
// Global OP
SmallInt operator+ ( const SmallInt& s1, const SmallInt& s2 ){
std::cout << "Called ::operator+()\n";
return s1._val + s2._val;
}
int main() {
NS::SmallInt s(1);
NS::SmallInt t = s + 2;
return 0;
}
#include <iostream>
namespace NS {
class SmallInt {
public:
SmallInt(int val) : _val(val) {
std::cout << "Called ctor\n";
}
int _val;
};
// Non-member OP
SmallInt operator+( SmallInt& s1, double dval ){
return s1._val+static_cast<int>(dval);
}
}
int main() {
NS::SmallInt s(1);
NS::SmallInt t = s + 2;
return 0;
}
#include <iostream>
namespace NS {
class SmallInt {
// Friend OP
friend SmallInt operator+( const SmallInt&, double );
public:
SmallInt(int val) : _val(val) {
std::cout << "Called ctor\n";
}
// Member OP
SmallInt operator+(int);
private:
int _val;
};
SmallInt operator+( const SmallInt& s, double dval ){
std::cout << "Called ctor A\n";
return s._val + dval;
}
// the type of the implied object parameter is SmallInt&
SmallInt SmallInt::operator+(int ival){
std::cout << "Called ctor B\n";
return this->_val + ival;
}
}
int main() {
NS::SmallInt s(1);
NS::SmallInt t = s + 2.0;
return 0;
}
int operator+(int, int)
double operator+(double, double)
T* operator+(T*, I)
T* operator+(I, T*)
The third and fourth declarations represent the built-in operator for pointer types, which is used to add values of integral type to pointer values.
X” where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration.
#include <iostream>
namespace NS {
class SmallInt {
// Friend OP
friend SmallInt operator+( const SmallInt&, double );
public:
SmallInt(int val) : _val(val) {
std::cout << "Called ctor\n";
}
// Member OP
SmallInt operator+(int);
private:
int _val;
};
SmallInt operator+( const SmallInt& s, double dval ){
std::cout << "Called ctor A\n";
return s._val + dval;
}
// the type of the implied object parameter is SmallInt&
SmallInt SmallInt::operator+(int ival){
std::cout << "Called ctor B\n";
return this->_val + ival;
}
}
int main() {
NS::SmallInt s(1);
NS::SmallInt t = s + 2.0;
return 0;
}
Since the type of the implied object parameter is SmallInt&, the member and non-member operator functions can be considered as:
SmallInt operator+(SmallInt&, int );
SmallInt operator+(const SmallInt&, double );
For the first argument, the member operator is a better match. For the second argument, non-member function is a better match. Since neither function is strictly better than the other in all arguments, the compiler reports an ambiguity error.