casting — Как C ++ неявно приводит аргументы к компаратору, такому как & lt ;?

Я думал, что это будет легко решить вопрос через Google, но я не могу найти окончательный (или даже умозрительный) ответ:

При использовании оператора сравнения, в каком порядке происходит неявное приведение?

int i = -1;
size_t t = 1;

bool result = i < t;

Это эквивалентно:

bool result = i < int(t);    // equals true

или же:

bool result = size_t(i) < t;    // equals false

Это легкая часть вопроса — вторая часть «каково общее правило», как это может быть:

  1. «Более простой» аргумент всегда преобразуется в «более сложный» аргумент (то есть size_t-> int), или
  2. Первый (или второй) аргумент всегда преобразуется в тип второго (или первого) аргумента, или
  3. Встроенные примитивы, такие как size_t и ints, имеют специальные операторы сравнения, которые определяют приведение в каждом конкретном случае.

Все три кажутся разумными, хотя второе даст значительно отличающееся поведение от того, что интуитивно ожидает большинство людей.

Компилятор VC ++, похоже, считает, что стоит сравнить предупреждение уровня 3, когда вы сравниваете int с size_t — и все же он выдает предупреждение уровня 4 только тогда, когда вы возвращаете отрицательное число из функции, которая возвращает size_t (что приводит к более половины максимального целого числа, возвращаемого).

В попытке избавиться от всех предупреждений уровня 4, я все равно явно произнесла все, но хотела знать «правду». Это должно быть определено где-то …

7

Решение

Правила довольно сложны и зависят от реализации.
В основном, однако:

  1. Оба типа «повышены». Это означает, что что-нибудь
    меньше чем int повышен до int, (В маловероятном случае
    тот size_t меньше чем int, он будет повышен до
    подписанный intи потерять свою неподписанность.)

  2. Если один из типов может содержать все значения
    другой, другой преобразуется в этот тип.

  3. Если один из типов не подписан, а другой подписан, и
    они имеют одинаковый размер, подпись преобразуется в
    без знака.

За int а также size_t (который должен быть без знака), это
означает, что если size_t меньше чем int, int будут
быть преобразован в size_t,

10

Другие решения

$ 18.2 / 6 — тип size_t определяется реализацией целое число без знака
тип, достаточно большой, чтобы содержать размер в байтах любого объекта.

$ 5.9 — Иначе, если операнд с целым типом без знака имеет
ранг больше или равен рангу типа другого
операнд, операнд со знаком целого типа должен быть преобразован в
тип операнда с целым типом без знака.
Для первого
часть, bool повышается до int, до преобразования, как указано
по стандарту C ++.

Таким образом, это означает, что «i» преобразуется в тип «size_t» (при условии, что size_t имеет тип «unsigned int» или более). Затем результаты, которые имеют тип «unsigned int», преобразуются в «bool» (это тип result).

Обратите внимание, что стандарт определяет, что ранг signed int а также unsigned int тот же самый.

Обратитесь к разделам 4 и 5 стандарта C ++ за точными правилами конверсии / продвижения по службе.

4