¿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) ...
¿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) ...
Si lo que desea es una macro sencilla, esto debería hacer el truco:
#define is_type_signed(my_type) (((my_type)-1) < 0)
Esta respuesta tiene una variable unitaria; esto no siempre funciona Necesita cambiar a: #define is_type_signed (my_type) (((my_type (0)) - 1) <0) –
Patrick J: En C++, el original funciona bien debido a la inicialización predeterminada. Tienes razón en C, sin embargo. – Branan
¿Cómo puede haber una variable no inicializada cuando las únicas variables son las temporales 0 y -1? –
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.
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. –
De acuerdo, pero se deben evitar las macros tanto como sea posible en C++ IMO. – ChrisN
De acuerdo, voté su respuesta, simplemente contrastándola con la respuesta aceptada actual. –
para C++, hay boost :: is_unsigned < T>. Tengo curiosidad por qué lo necesita, sin embargo, hay algunas buenas razones en mi humilde opinión.
Necesito calcular el valor máximo y mínimo para una variable de tipo entero, dado su tipo. – botismarius
Puede usar std :: numeric_limits <> :: max() y std :: numeric_limits <> :: min() para obtener los valores máximos y mínimos para un tipo. – ChrisN
Si querías eso, ¿por qué no lo preguntaste en primer lugar? –
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.
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
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 ...
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>.
No existe tal cosa como typeof() en C++. Pero en C++ 11 hay decltype (variable), que hace la cosa. – mcv
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
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;
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
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;
}
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. –
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
¿Puede explicar por favor qué "ciertas cosas" no se pueden hacer sin las macros? –