2015-07-11 5 views
0

Итак, из того, что я знаю, поведение следующих двух функций должно быть точно таким же. Однако, если я реализую с использованием первого, компилятор, похоже, не может понять, что он эквивалентен второму. Есть ли вообще намек на компилятор, чтобы использовать второй?Как заставить компилятор C++ использовать подписанный трюк без знака для оптимизации сравнения

Другими словами, я ненавижу делать вещи static_cast ... Во всяком случае, чтобы избежать этого?

// In my real use case, range will never be negative.... 
// All I want is to return (diff > range || diff < 0) assuming range >=0 
bool IsOutofRange1(int diff, int range) { 
    if ((range >= 0) && (diff > range || diff < 0)) return true; 
    if (range < 0 && diff > range && diff < 0) return true; 
    return false; 
} 

bool IsOutofRange2(int diff, int range) { 
    if (static_cast<unsigned>(diff) > static_cast<unsigned>(range)) return true; 
    return false; 
} 
+0

Почему вы ненавидите 'static_cast'? – GWW

+2

@GWW Ну, вы должны ненавидеть все броски. – emlai

+2

http://stackoverflow.com/questions/31347420/can-we-and-how-safe-is-to-signed-to-unsigned-trick-to-save-one-comparison-in – Steephen

ответ

0

Если ваш диапазон никогда не отрицательный, почему вы используете для него подписанный тип (да, я знаю, вы ненавидите кастинг)? Как насчет перегрузки:

bool IsOutofRange(int diff, int range) 
{ 
    .... 
} 

bool IsOutofRange(int diff, unsigned range) 
{ 
    if (static_cast<unsigned>(diff) > range) return true; 
    return false; 
} 

Конечно, чтобы заставить компилятор использовать второй вариант вы бы (о боже мой ...):

IsOutofRange(diff,static_cast<unsigned>(range)); 

Я надеюсь, что помогает, и я глубоко сожалею о static_cast'ing.