С ++ отрицание и разрешение перегрузки
В Microsoft Visual Studio 2015 следующий код:
void foo(int8_t a);
void foo(int16_t a);
void foo(int16_t a, int16_t b);
void f()
{
int8_t x /* = some value */;
foo(-int16_t(x)); // ERROR
}
Дает следующее сообщение:
foo
Error: more than one instance of overloaded function "function" matches the argument list:
function "foo(int8_t a)"
function "foo(int16_t a)"
argument types are: (int)
Что здесь происходит? Разве это не должно сказать "типы аргументов: (int16_t)"? Это как-то связано с продвижением? если так, как я могу отключить продвижение?
2 ответа
Отрицание, прежде чем бросить. Отрицание приводит к целочисленному размеру машины, отсюда и неоднозначность.
foo(int16_t(-x));
Вы забываете о целочисленных акциях. Все арифметические операторы выполняют целочисленные преобразования в операндах, для которых выполняется арифметика.
В выражении -a
, для любого a
целочисленные продвижения применяются к a
, Результатом этого является то, что если a
целочисленный тип уже int
, то значение повышается до int
,
В вашей системе int
32-битный, так int16_t
поэтому уже -(int16_t)x
средства -(int)(int16_t)x
,
Если вы хотите сделать отрицание в 16-битной точности: вы не можете; ты должен сделать это в int
точность, а затем преобразовать результат обратно в 16-бит.
В этом случае foo( (int16_t)-x )
Это самый простой способ, хотя в общем подумайте о том, что вы отрицаете. Вот -x
является -(int)x
но в этом случае это, вероятно, то, что вы действительно хотите сделать. Если бы мы использовали неподписанные типы, вам нужно было бы проявлять больше внимания.