C ++ Как проверить, что функция получает беззнаковое int?

У меня есть функция, объявленная как:

void foo(unsigned int x)

Как я могу проверить, что foo () не получает отрицательные числа?
Я хотел бы, чтобы, если я вызову foo (-1), было сгенерировано исключение,
но, разумеется, поскольку x автоматически преобразуется в unsigned, я не могу проверить его положительность, например:

if not(x>=0){ do_something();};

или аналогичные проверки.

2

Решение

На самом деле нет хорошего способа сделать это, но вы можете сделать это с помощью некоторых приемов:

1) объявить неопределенное лучшее совпадение:

void foo(unsigned int x) {
//do something
}

void foo(int x);

2) используйте typeid для определения типа.

2

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

Вы определили функцию, поэтому она занимает unsigned int аргумент, поэтому он не может получить отрицательное значение.

Если вы называете это с int аргумент, что значение будет неявно преобразовано из int в unsigned intи результат этого преобразования хорошо определен. Это особенность языка, и вы не можете отключить его, если ваш компилятор не предоставит вам способ сделать это — и я не знаю, какой компилятор это делает.

Что касается вашей функции, эти два вызова:

foo(-1);       /* -1 is converted to unsigned int, to the value UINT_MAX */
foo(UINT_MAX);

неразличимы. И это не единственный случай; любой отрицательный int значение будет преобразовано в действительный unsigned значение.

Если очень большие значения считаются недействительными для foo()затем вы можете проверить, что значение параметра находится в некотором «разумном» диапазоне, но определить, что является «разумным», не всегда легко.

2

Как следует из ответа, вы можете добавить перегруженную версию foo это занимает int аргумент. И так как вы сказали, что хотели foo(-1) чтобы бросить исключение, вы можете просто перегрузить foo() сделай это:

#include <iostream>

class Wrong_Type {
public:
Wrong_Type(){}
};

void foo(unsigned n) {
std::cout << "In foo, unsigned n = " << n << "\n";
}

void foo(int n) {
std::cout << "In foo, int n = " << n << "\n";
throw Wrong_Type();
}

int main() {
try {
foo(-1);
}
catch (Wrong_Type) {
std::cout << "Caught Wrong_Type exception\n";
}
}

Когда я запускаю это, вывод:

In foo, int n = -1
Caught Wrong_Type exception

Но это не идеальное решение, поскольку оно выдает исключение, основанное на тип аргумента, а не его значение. И то и другое 1 а также -1 имеют тип intтак зовет foo(1) также выбросит исключение. И некоторые другие действительные звонки, такие как foo(1.0)стань неоднозначным.

Если вы можете заменить foo(1) от foo(1U), где 1U константа типа unsigned intТогда это может сработать.

1

Я не эксперт по С ++, но …

У вас есть только фиксированное количество бит (обычно 32 или 64) для представления целого числа. Если вы знаете, что у вас никогда не будет целого числа меньше нуля, вы можете использовать все эти биты и хранить гораздо большее число. Если возможно, что ваше число меньше нуля, то компилятор должен зарезервировать немного для знака.

Это становится немного сложнее, чем это — см. Статья в Википедии о 2-х дополнениях.

Короче говоря, внутри foo, если вы видите, что x «действительно очень большой», вам, возможно, передали отрицательное число.

Проверьте ваши документы компилятора на размер int vs uint.

Возможно, вы захотите либо изменить свой параметр на обычное целое число void foo(int x) или просто расслабьтесь, зная, что с вашей текущей установкой x никогда не будет меньше нуля.

0
По вопросам рекламы [email protected]