Макрос для проверки, является ли целочисленный тип подписанным или неподписанным - PullRequest
17 голосов
/ 15 сентября 2008

Как бы вы написали (в C / C ++) макрос, который проверяет, является ли целочисленный тип (заданный как параметр) со знаком или без знака?


      #define is_this_type_signed (my_type) ...

Ответы [ 11 ]

39 голосов
/ 15 сентября 2008

В C ++ используйте std::numeric_limits<type>::is_signed.

#include <limits>
std::numeric_limits<int>::is_signed  - returns true
std::numeric_limits<unsigned int>::is_signed  - returns false

См. http://msdn.microsoft.com/en-us/library/85084kd6(VS.80).aspx.

26 голосов
/ 15 сентября 2008

Если вам нужен простой макрос, это должно сработать:

#define is_type_signed(my_type) (((my_type)-1) < 0)
4 голосов
/ 15 сентября 2008

Если вы хотите макрос, то это должно сработать:

#define IS_SIGNED( T ) (((T)-1)<0)

В основном, приведите -1 к вашему типу и посмотрите, все ли равно -1. В C ++ вам не нужен макрос. Просто #include <limits> и:

bool my_type_is_signed = std::numeric_limits<my_type>::is_signed;
1 голос
/ 16 сентября 2008

Althout typeof на данный момент не является допустимым C ++, вместо этого вы можете использовать шаблонный вывод. Смотрите пример кода ниже:

#include <iostream>
#include <limits>

template <typename T>
bool is_signed(const T& t)
{
  return std::numeric_limits<T>::is_signed;
}

int main()
{
  std::cout << 
    is_signed(1) << " " << 
    is_signed((unsigned char) 0) << " " << 
    is_signed((signed char) 0) << std::endl;
}

Этот код напечатает

  1 0 1
1 голос
/ 15 сентября 2008

В C ++ вы можете сделать:


bool is_signed = std::numeric_limits<typeof(some_integer_variable)>::is_signed;

numeric_limits определено в заголовке .

1 голос
/ 15 сентября 2008

На самом деле, сегодня я просто удивлялся тому же Кажется, работает следующее:

#define is_signed(t)    ( ((t)-1) < 0 )

Я проверял с:

#include <stdio.h>

#define is_signed(t)    ( ((t)-1) < 0 )
#define psigned(t) printf( #t " is %s\n", is_signed(t) ? "signed" : "unsigned" );

int
main(void)
{
    psigned( int );
    psigned( unsigned int );
}

который печатает:

int is signed
unsigned int is unsigned
1 голос
/ 15 сентября 2008

Ваше требование не совсем лучшее, но если вы хотите взломать определение, один из вариантов может быть:

#define is_numeric_type_signed(typ) ( (((typ)0 - (typ)1)<(typ)0) && (((typ)0 - (typ)1) < (typ)1) )

Однако, это не считается хорошим или переносимым каким-либо образом.

0 голосов
/ 12 января 2017

Более «современный» подход заключается в использовании type_traits:

#include <type_traits>
#include <iostream>
int main()
{
    std::cout << ( std::is_signed<int>::value ? "Signed" : "Unsigned") <<std::endl;
}
0 голосов
/ 15 сентября 2008

В C вы не можете написать макрос, который работает с пока неизвестными определениями типов целочисленных типов.

В C ++ вы можете, если ваш тип является фундаментальным целочисленным типом или typedef фундаментального целочисленного типа. Вот что вы будете делать в C ++:

template <typename T>
struct is_signed_integer
{
    static const bool value = false;
};

template <>
struct is_signed_integer<int>
{
    static const bool value = true;
};

template <>
struct is_signed_integer<short>
{
    static const bool value = true;
};

template <>
struct is_signed_integer<signed char>
{
    static const bool value = true;
};

template <>
struct is_signed_integer<long>
{
    static const bool value = true;
};

// assuming your C++ compiler supports 'long long'...
template <>
struct is_signed_integer<long long>
{
    static const bool value = true;
};

#define is_this_type_signed(my_type) is_signed_integer<my_type>::value
0 голосов
/ 15 сентября 2008

Вы могли бы сделать это лучше с помощью функции шаблона, с меньшим количеством макросов.

    template <typename T>
        bool IsSignedType()
        {
           // A lot of assumptions on T here
           T instanceAsOne = 1;

           if (-instanceAsOne > 0)
           {
               return true;
           }
           else
           {
               return false;
           }
}

Простите за форматирование ...

Я бы попробовал это и посмотрел, работает ли он ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...