Предположим, у меня есть некоторый шаблонный код, который выполняет следующее:
T x = foo();
T y = -x;
Теперь, если T не числовой тип (или в котором не реализован унарный минус), компиляция просто не удастся. Но если это unsigned int, unsigned short и т. Д., Это будет успешно, с предупреждением. Так что я хотел бы иметь возможность сделать
T x = foo();
if (/* magic condition */ {
T y = -x;
}
Могу ли я написать в выражении условие — которое проверяется во время компиляции или во время выполнения — типа T является неким числовым типом со знаком? например используя typeid?
Замечания:
C ++ 11 имеет is_unsigned
черта, которую вы можете использовать в static_assert
:
#include <type_traits>
template <typename T>
void foo()
{
static_assert(std::is_unsigned<T>::value);
T x = /* ... */
T y = -x;
/* ... */
}
Если вам нужно, чтобы проверка была более динамичной, просто вставьте ее в if
состояние:
template <typename T>
void foo()
{
if (!std::is_unsigned<T>::value) {
/* To arrive here and for the following
not to error out, we must have a numeric
type that's not unsigned! */
T x = /* ... */
T y = -x;
}
else {
/* Do something else for unsigned numeric
types */
}
}
Более сложные решения связаны с перегрузками, std::enable_if
и все виды других шаблонных мета-хакеров, но все, что вам нужно, может быть выше.
Да, ты можешь.
static_assert(std::is_unsigned<T>::value, "Not unsigned!");
(Вы должны включить type_traits, чтобы это работало.)
Затем вы можете корректировать процесс компиляции, даже если enable_if
если ты уверен, что другого пути нет :).