Проверка типа времени компиляции с использованием логики ветвления

Я пытаюсь определить, есть ли способ во время компиляции выполнить проверку условий для двух разных типов одновременно.

Пример:

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,

Другие вопросы по тегам