Я не думаю, что это так просто, как принимая тип на правой стороне
Для базового типа умозаключений формы auto var = some_expression;
, это именно так просто. Каждое хорошо типизированное выражение имеет ровно один тип, и этот тип будет типом var
. Не будет никакого неявного преобразования из типа выражения в другой тип (как может быть, если вы указали явный тип для var
).
что, если у вас что-то вроде:
5 + 3.4
вопрос "? Что такое тип 5 + 3.4
" не является специфическим для вывода типа, компиляторы C++ всегда должны были ответить на этот вопрос - даже до ввода типа.
Итак, давайте сделаем шаг назад и посмотреть на то, как компилятор C++ typechecks в заявлении some_type var = some_expression;
:
Сначала он определяет тип some_expression
. Поэтому в коде вы можете себе представить что-то вроде Type exp_type = type_of(exp);
. Теперь он проверяет, равен ли exp_type
some_type
или существует неявное преобразование от exp_type
до some_type
. Если это так, оператор хорошо типизирован и var
вводится в окружающую среду как имеющий тип some_type
. Иначе это не так.
Теперь, когда мы вводим определение типа и писать auto var = some_expression;
, изменения уравнение, как например: Мы до сих пор Type exp_type = type_of(exp);
, но вместо того, чтобы затем сравнить его с другим типом или применения каких-либо неявные преобразования, мы вместо того, чтобы просто установить exp_type
как тип var
,
Итак, давайте вернемся к 5 + 3.4
. Каков его тип и как его определяет компилятор? В C++ его тип - double
. Правила определения типа арифметического выражения перечислены в стандарте C++ (ищите «обычные арифметические преобразования», но в основном сводятся к следующему: из двух типов операндов выберите тот, который может представлять больший диапазон значений. Если тип меньше int
, преобразуйте оба операнда в int
. В противном случае преобразуйте оба операнда в выбранный вами тип.
В коде вы бы осуществить это путем присвоения каждому числовому типу ранг преобразования, а затем сделать что-то вроде этого:
Type type_of_binary_arithmetic_expression(Type lhs_type, Type rhs_type) {
int lhs_rank = conversion_rank(lhs_type);
int rhs_rank = conversion_rank(rhs_type);
if(lhs_rank < INT_RANK && rhs_rank < INT_RANK) return INT_TYPE;
else if(lhs_rank < rhs_rank) return rhs_type;
else return lhs_type;
}
Предположительно правила Go несколько отличаются, но те же самые принципы применимы.
Это больше похоже на: * "если left целое, а справа - float, конвертируйте left to float и добавьте два поплавка" *. Преобразования выполняются (по мере необходимости) для каждого двоичного оператора в выражении, и результат заканчивается наивысшим ранжирующим типом в выражении. – user3386109