c++ - tener - Macro para probar si un tipo entero está firmado o sin firmar
pie de firma excel (11)
Aunque el typeof
no es legal C ++ en este momento, puedes usar la deducción de la plantilla. Vea el código de muestra a continuación:
#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 se imprimirá
1 0 1
¿Cómo escribiría (en C / C ++) una macro que prueba si un tipo entero (dado como parámetro) está firmado o no?
#define is_this_type_signed (my_type) ...
En C ++ puedes hacer:
bool is_signed = std::numeric_limits<typeof(some_integer_variable)>::is_signed;
numeric_limits se define en el encabezado <limits>.
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 .
En C, no puede escribir una macro que funcione en typedef aún desconocidos de tipos enteros fundamentales.
En C ++, puede hacerlo siempre que su tipo sea un tipo de entero fundamental o un typedef de un tipo entero fundamental. Esto es lo que harías 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
En realidad, me estaba preguntando lo mismo hoy. Lo siguiente parece funcionar:
#define is_signed(t) ( ((t)-1) < 0 )
Probé 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
Para c ++, hay boost :: is_unsigned <T>. Tengo curiosidad por qué lo necesita, sin embargo, hay algunas buenas razones en mi humilde opinión.
Podrías hacerlo mejor con una función de plantilla, menos negocios desagradables.
template <typename T>
bool IsSignedType()
{
// A lot of assumptions on T here
T instanceAsOne = 1;
if (-instanceAsOne > 0)
{
return true;
}
else
{
return false;
}
}
Perdona el formateo ...
Lo probaría y vería si funciona ...
Si lo que quieres es una macro simple, esto debería ser el truco:
#define is_type_signed(my_type) (((my_type)-1) < 0)
Si quieres una macro, entonces esto debería ser el truco:
#define IS_SIGNED( T ) (((T)-1)<0)
Básicamente, lanza -1 a tu tipo y mira si todavía es -1. En C ++ no necesitas una macro. Solo #include <limits>
y:
bool my_type_is_signed = std::numeric_limits<my_type>::is_signed;
Su requisito no es exactamente el mejor, pero si desea hackear 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 bueno ni portátil de ninguna manera.
Un enfoque más "moderno" es usar type_traits
:
#include <type_traits>
#include <iostream>
int main()
{
std::cout << ( std::is_signed<int>::value ? "Signed" : "Unsigned") <<std::endl;
}