2008-09-15 8 views
17

¿Cómo escribiría (en C/C++) una macro que verifica si un tipo entero (dado como parámetro) está firmado o no?Macro para comprobar si un tipo entero está firmado o no

 

     #define is_this_type_signed (my_type) ... 

+1

C y C++ son dos idiomas distintos, pero relacionados. Desea tener esto en cuenta: las macros son una gran solución en C, pero son peligrosas y, en su mayoría, innecesarias en C++. Las macros completan completamente el cortocircuito con la comprobación de tipos en C++, solo para empezar. –

+1

Hay ciertas cosas que no puede hacer sin macros. De todos modos, es necesario algún código C/C++ si desea hacer algo similar en una plantilla de C++. – botismarius

+1

¿Puede explicar por favor qué "ciertas cosas" no se pueden hacer sin las macros? –

Respuesta

25

Si lo que desea es una macro sencilla, esto debería hacer el truco:

#define is_type_signed(my_type) (((my_type)-1) < 0) 
+1

Esta respuesta tiene una variable unitaria; esto no siempre funciona Necesita cambiar a: #define is_type_signed (my_type) (((my_type (0)) - 1) <0) –

+0

Patrick J: En C++, el original funciona bien debido a la inicialización predeterminada. Tienes razón en C, sin embargo. – Branan

+13

¿Cómo puede haber una variable no inicializada cuando las únicas variables son las temporales 0 y -1? –

39

En C++, use 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 

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

+1

No es técnicamente un "macro" según lo solicitado, pero sin duda es el método más estándar para un tipo incorporado. –

+1

De acuerdo, pero se deben evitar las macros tanto como sea posible en C++ IMO. – ChrisN

+0

De acuerdo, voté su respuesta, simplemente contrastándola con la respuesta aceptada actual. –

0

para C++, hay boost :: is_unsigned < T>. Tengo curiosidad por qué lo necesita, sin embargo, hay algunas buenas razones en mi humilde opinión.

+0

Necesito calcular el valor máximo y mínimo para una variable de tipo entero, dado su tipo. – botismarius

+0

Puede usar std :: numeric_limits <> :: max() y std :: numeric_limits <> :: min() para obtener los valores máximos y mínimos para un tipo. – ChrisN

+1

Si querías eso, ¿por qué no lo preguntaste en primer lugar? –

1

Su exigencia no es exactamente la mejor, pero si desea cortar juntos una definición, una opción podría ser:

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

Sin embargo, esto no se considera agradable o portátil mediante cualquier medio.

1

En realidad, me preguntaba lo mismo hoy. El siguiente parece funcionar:

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

He probado con:

#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); 
} 

que imprime:

int is signed 
unsigned int is unsigned 
-1

Se podría hacer esto mejor con una función de plantilla, menos desagradable asunto macro.

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

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

perdonar al formato ...

me gustaría probar esto y ver si funciona ...

1

En C++ que puede hacer:


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

numeric_limits se define en el encabezado < limits>.

+1

No existe tal cosa como typeof() en C++. Pero en C++ 11 hay decltype (variable), que hace la cosa. – mcv

-1

En C, no se puede escribir una macro que funcione en typedef aún desconocidos de tipos enteros fundamentales.

En C++, puede siempre que su tipo sea un tipo de entero fundamental o un typedef de un tipo entero fundamental. Esto es lo que haría en 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 
4

Si desea que una macro entonces esto debe hacer el truco:

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

Básicamente, fundido -1 a su tipo y ver si todavía -1 . En C++ no necesitas una macro.Sólo #include <limits> y:

bool my_type_is_signed = std::numeric_limits<my_type>::is_signed; 
1

Althout typeof no es legal C++ en este momento, puede utilizar la deducción de plantilla en su lugar. Ver código de ejemplo siguiente:

#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; 
} 

Este código imprimirá

1 0 1 
0

Un enfoque más "moderna" es utilizar type_traits:

#include <type_traits> 
#include <iostream> 
int main() 
{ 
    std::cout << (std::is_signed<int>::value ? "Signed" : "Unsigned") <<std::endl; 
} 
Cuestiones relacionadas