Проверка типа времени компиляции с использованием логики ветвления
Я пытаюсь определить, есть ли способ во время компиляции выполнить проверку условий для двух разных типов одновременно.
Пример:
template <typename T>
class MyClass
{
returnVal myFunction() const
{
// Is there a compile time way of doing this? std::conditional?
return myConditionFunction(std::is_same<char, T> || std::is_same<unsigned char, T>);
}
returnVal myConditionFunction(std::true_type& const) const
{
// perform calculations on char or unsigned char
}
returnVal myConditionFunction(std::false_type& const) const
{
// perform calculations on non-char/unsigned char types
}
};
Я хочу вызвать функцию, если тип char или unsigned char.
Изменить: Обновлен код, чтобы показать, что я использую шаблонный класс.
2 ответа
Вы можете использовать условия для генерации постоянной времени компиляции, а также для создания типа, который будет соответствовать true_type
или же false_type
:
returnVal myFunction() const
{
typedef std::integral_constant<bool,
std::is_same<unsigned char, T>::value
|| std::is_same< char, T>::value> selector;
return myConditionFunction(selector());
}
Обратите внимание, что std::true_type
просто std::integral_constant<bool,true>
и аналогично для std::false_type
,
Есть много способов сделать то, что вы хотите. Если вы не хотите писать новые шаблоны самостоятельно, вы можете сделать что-то вроде этого (псевдокод, так как returnVal
не указан, и T
не указывается и не выводится откуда-либо):
#include <type_traits>
returnVal myFunction() const
{
return myConditionFunction(
typename std::is_same<unsigned char, typename std::make_unsigned<T>::type>::type());
}
returnVal myConditionFunction(std::true_type& const) const
{
}
returnVal myConditionFunction(std::false_type& const) const
{
}
Это использует std::make_unsigned
мета-функция из библиотеки признаков типа для преобразования T
к какому-либо неподписанному (так, если T
является char
или же unsigned char
, std::make_unsigned<T>::type
будет unsigned char
). Затем, std::is_same
Результат используется для отправки к соответствующей реализации функции.
В качестве альтернативы, вы можете написать свою собственную черту:
template <typename T>
struct is_char_or_uchar
{
typedef false_type type;
static const bool value = false;
}
template<>
struct is_char_or_uchar<char>
{
typedef true_type type;
static const bool value = true;
}
template<>
struct is_char_or_uchar<signed char>
{
typedef true_type type;
static const bool value = true;
}
template<>
struct is_char_or_uchar<unsigned char>
{
typedef true_type type;
static const bool value = true;
}
И используйте это так:
returnVal myFunction() const
{
return myConditionFunction(typename is_char_or_uchar<T>::type());
}
returnVal myConditionFunction(std::true_type& const) const
{
}
returnVal myConditionFunction(std::false_type& const) const
{
}
В качестве альтернативы, если у вас есть Boost, вы можете использовать boost::mpl::or_
и два вызова std::is_same
,