Разрешение перегрузки унарных операторов

Операция вида op x или x op, где op — это унарный оператор, допускающий перегрузку, а x — это выражение типа X, выполняется следующим образом.

· С помощью правил из раздела §7.3.5 определяется набор пользовательских операторов-кандидатов, предоставленных в типе X для операции operator op(x).

· Если набор пользовательских операторов-кандидатов не пустой, то он становится набором операторов-кандидатов для операции. В противном случае набором операторов-кандидатов для операции становятся стандартные реализации унарного оператора operator op, включая их варианты с нулификацией. Стандартные реализации данного оператора указываются в описании оператора (§7.6 и §7.7).

· Чтобы выбрать оператор, более всего подходящий для списка аргументов (x), к набору операторов-кандидатов применяются правила разрешения перегрузки из раздела §7.5.3, и этот оператор становится результатом процесса разрешения перегрузки. Если при разрешении перегрузки не удалось выбрать один подходящий оператор, то возникает ошибка времени привязки.

Разрешение перегрузки бинарных операторов

Операция вида x op y, где op — это бинарный оператор, допускающий перегрузку, x — это выражение типа X, а y — это выражение типа Y, выполняется следующим образом.

· Определяется набор пользовательских операторов-кандидатов, предоставленных типами X и Y для операции operator op(x, y). Этот набор представляет собой объединение операторов-кандидатов, предоставленных в типе X, и операторов-кандидатов, предоставленных в типе Y. Каждый из этих составляющих наборов определяется в соответствии с правилами из раздела §7.3.5. Если X и Y представляют один тип или X и Y являются производными от общего базового типа, тогда в объединенном наборе общие операторы-кандидаты появляются только один раз.

· Если набор пользовательских операторов-кандидатов не пустой, то он становится набором операторов-кандидатов для операции. В противном случае набором операторов-кандидатов для операции становятся стандартные реализации бинарного оператора operator op, включая их варианты с нулификацией. Стандартные реализации данного оператора указываются в описании оператора (§7.8–§7.12). Для предопределенных операторов перечислений и делегатов рассматриваются только операторы, определяемые типом перечисления или делегата, который является типом времени привязки одного из операндов.

· Чтобы выбрать оператор, более всего подходящий для списка аргументов (x, y), к набору операторов-кандидатов применяются правила разрешения перегрузки из раздела §7.5.3, и этот оператор становится результатом процесса разрешения перегрузки. Если при разрешении перегрузки не удалось выбрать один подходящий оператор, то возникает ошибка времени привязки.

Пользовательские операторы-кандидаты

Если взять тип T и операцию operator op(A), где op — это оператор, допускающий перегрузку, а A — это список аргументов, то набор пользовательских операторов-кандидатов, предоставляемых типом T для оператора operator op(A), определяется следующим образом.

· Определяется тип T0. Если тип T допускает значения NULL, T0 является его базовым типом, в противном случае T0 совпадает с T.

· Для всех объявлений operator op в T0 и всех вариантов таких операторов с нулификацией, если в соответствии со списком аргументов A применим хотя бы один оператор (§7.5.3.1), то набор операторов-кандидатов состоит из всех таких применимых операторов в T0.

· В противном случае, если T0 является типом object, набор операторов-кандидатов является пустым.

· Иначе набор операторов-кандидатов, предоставленных в T0, является набором операторов-кандидатов, предоставленных в непосредственном базовом классе для T0 или в фактическом базовом классе для T0, если T0 является параметром типа.

Числовое расширение

Числовое расширение — это автоматическое проведение определенных неявных преобразований операндов в стандартных унарных и бинарных числовых операторах. Числовое расширение — это не отдельный механизм, а скорее эффект от проведения разрешения перегрузки для стандартных операторов. Числовое расширение специально не влияет на вычисление пользовательских операторов, хотя пользовательские операторы можно реализовать для получения похожих эффектов.

В качестве примера числового расширения можно рассмотреть стандартные реализации бинарного оператора *:

int operator *(int x, int y);
uint operator *(uint x, uint y);
long operator *(long x, long y);
ulong operator *(ulong x, ulong y);
float operator *(float x, float y);
double operator *(double x, double y);
decimal operator *(decimal x, decimal y);

При применении правил разрешения перегрузки (§7.5.3) к этому набору операторов результатом является первый оператор, для которого существуют неявные преобразования операндов. Например, для операции b * s, где b имеет тип byte, а s — тип short, при разрешении перегрузки в качестве наилучшего оператора будет выбран operator *(int, int). Таким образом, b и s преобразуются в тип int, и результат имеет тип int. Аналогичным образом, для операции i * d, где i имеет тип int, а d — тип double, при разрешении перегрузки в качестве наилучшего оператора будет выбран operator *(double, double).

Наши рекомендации