почему бы не сделать x типом unsigned char и привести его? неужели вам не нужно сдвигать более 255 бит?
const unsigned char x = static_cast<unsigned char>(A - B);
или, возможно, используйте маскирование, чтобы гарантировать, что сдвиг будет в границах, подобных этому:
const unsigned int x = static_cast<unsigned int>(A - B) & 0x1f; // limit A-B to have a range of (0 - 31)
EDIT:
в ответ на комментарий вот идея:
template<unsigned int A, unsigned int B>
int foo() {
int v = 1;
const int x = A - B;
if (x > 0) {
v = v << (static_cast<unsigned int>(x) & 0x1f);
}
bar(v);
}
ПРИМЕЧАНИЕ: вы можете заменить 0x1f на что-то вроде: (CHAR_BIT * sizeof (T) - 1)
РЕДАКТИРОВАТЬ: в ответ на последний комментарий этот код не выдает никаких предупреждений, компилируя с: g ++ -W -Wall -ansi -pedantic test.cc -o test
#include <iostream>
template<unsigned int A, unsigned int B>
int foo() {
int v = 1;
const int x = A - B;
if (x > 0) {
v = v << (static_cast<unsigned int>(x) & 0x1f);
}
return v;
}
int main() {
std::cout << foo<1, 3>() << std::endl;
std::cout << foo<3, 1>() << std::endl;
std::cout << foo<300, 1>() << std::endl;
std::cout << foo<25, 31>() << std::endl;
}