Приведение к int или float в зависимости от is_integer - PullRequest
2 голосов
/ 14 января 2011

У меня есть какой-то тип T, и в некоторых случаях это может быть, например, char, но я хочу вывести его целое значение, а не символ. Для этого есть следующее:

typedef ( std::numeric_limits< T >::is_integer ? int : float ) FormatType;
os << static_cast< FormatType >( t );

Однако это не скомпилируется, указав "error C2275: 'int' : illegal use of this type as an expression". Префикс int и float с typename не решает проблему. Что мне здесь не хватает?

Следующее, что я считаю эквивалентным, работает:

if( std::numeric_limits< T >::is_integer )
{
    os << static_cast< int >( t );
}
else
{
    os << static_cast< float >( t );
}

Ответы [ 3 ]

3 голосов
/ 14 января 2011

Что мне здесь не хватает?

Вы пытаетесь использовать типы в качестве выражений. C ++ просто не позволяет этого. Вместо этого вы можете использовать так называемое время компиляции if через метапрограммирование. Например, я считаю, что Boost предлагает следующее:

typedef if_<std::numeric_limits< T >::is_integer, int, double>::type FormatType;

os << static_cast< FormatType >( t );

С другой стороны, ваше второе решение работает хорошо, и компилятор выяснит, что одна из ветвей никогда не будет истинной, и устранит его. Таким образом, производительность будет одинаковой в обоих случаях (фактически должен быть сгенерирован точно такой же код).

2 голосов
/ 14 января 2011

Попробуйте использовать интегральное повышение:

os << +t;

Вы получите int из него для целочисленного типа или вашего исходного типа с плавающей точкой, если он был одним.

0 голосов
/ 14 января 2011

GCC принимает это, не уверен в других:

template<bool Expression, typename TrueResult, typename FalseResult>
  class conditional_type;

template<typename TrueResult, typename FalseResult>
class conditional_type<1, TrueResult, FalseResult> {
public:
    typedef TrueResult R;
};

template<typename TrueResult, typename FalseResult>
class conditional_type<0, TrueResult, FalseResult> {
public:
    typedef FalseResult R;
};

typedef conditional_type<std::numeric_limits<T>::is_integer,int,float>::R FormatType;
...