SmallInt operator+ ( const SmallInt &, const SmallInt & );
int main() {
SmallInt si(98);
int iobj = 65;
int res = si + iobj; // ::operator+() - функция-кандидат
}
* множество операторов, объявленных в пространстве имен, в котором определен тип операнда. Если операнд имеет тип класса и этот тип объявлен в пользовательском пространстве имен, то операторные функции, объявленные в том же пространстве и имеющие то же имя, что и использованный оператор, считаются кандидатами:
namespace NS {
class SmallInt { /* ... */ };
SmallInt operator+ ( const SmallInt&, double );
}
int main() {
// si имеет тип SmallInt:
// этот класс объявлен в пространстве имен NS
NS::SmallInt si(15);
// NS::operator+() - функция-кандидат
int res = si + 566;
return 0;
}
* Операнд si имеет тип класса SmallInt, объявленного в пространстве имен NS. Поэтому перегруженный operator+(const SmallInt, double), объявленный в том же пространстве, добавляется к множеству кандидатов; множество операторов, объявленных друзьями классов, к которым принадлежат операнды. Если операнд принадлежит к типу класса и в определении этого класса есть одноименные применяемому оператору функции-друзья, то они добавляются к множеству кандидатов:
namespace NS {
class SmallInt {
friend SmallInt operator+( const SmallInt&, int )
{ /* ... */ }
};
}
int main() {
NS::SmallInt si(15);
// функция-друг operator+() - кандидат
int res = si + 566;
return 0;
}
* Операнд si имеет тип SmallInt. Операторная функция operator+(const SmallInt&, int), являющаяся другом этого класса, – член пространства имен NS, хотя непосредственно в этом пространстве она не объявлена. При обычном поиске в NS эта операторная функция не будет найдена. Однако при использовании operator+() с аргументом типа SmallInt функции-друзья, объявленные в области видимости этого класса, включаются в рассмотрение и добавляются к множеству кандидатов. Эти три множества операторных функций-кандидатов формируются точно так же, как и для вызовов обычных функций с аргументами типа класса. Однако при использовании операторного синтаксиса строятся еще два множества: множество операторов-членов, объявленных в классе левого операнда. Если такой операнд оператора operator+() имеет тип класса, то в множество функций-кандидатов включаются объявления operator+(), являющиеся членами этого класса:
class myFloat {
myFloat( double );
};
class SmallInt {
public:
SmallInt( int );
SmallInt operator+ ( const myFloat & );
};
int main() {
SmallInt si(15);
int res = si + 5.66; // оператор-член operator+() - кандидат
}
* Оператор-член SmallInt::operator+(const myFloat &), определенный в SmallInt, включается в множество функций-кандидатов для разрешения вызова operator+() в main(); множество встроенных операторов. Учитывая типы, которые можно использовать со встроенным operator+(), кандидатами являются также:
int operator+( int, int );
double operator+( double, double );
T* operator+( T*, I );
T* operator+( I, T* );
Первое объявление относится к встроенному оператору для сложения двух значений целых типов, второе – к оператору для сложения значений типов с плавающей точкой. Третье и четвертое соответствуют встроенному оператору сложения указательных типов, который используется для прибавления целого числа к указателю. Два последних объявления представлены в символическом виде и описывают целое семейство встроенных операторов, которые могут быть выбраны компилятором на роль кандидатов при обработке операций сложения.
Любое из первых четырех множеств может оказаться пустым. Например, если среди членов класса SmallInt нет функции с именем operator+(), то четвертое множество будет пусто.
Все множество операторных функций-кандидатов является объединением пяти подмножеств, описанных выше:
namespace NS {
class myFloat {
myFloat( double );
};
class SmallInt {
friend SmallInt operator+( const SmallInt &, int ) { /* ... */ }
public:
SmallInt( int );
operator int();