С ++ отрицание и разрешение перегрузки

В 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 но в этом случае это, вероятно, то, что вы действительно хотите сделать. Если бы мы использовали неподписанные типы, вам нужно было бы проявлять больше внимания.

Другие вопросы по тегам