Comment écrivez-vous (en C/C++) une macro qui teste si un type entier (donné en paramètre) est signé ou non signé?Macro pour tester si un type entier est signé ou non
#define is_this_type_signed (my_type) ...
Comment écrivez-vous (en C/C++) une macro qui teste si un type entier (donné en paramètre) est signé ou non signé?Macro pour tester si un type entier est signé ou non
#define is_this_type_signed (my_type) ...
Si ce que vous voulez est une macro simple, cela devrait faire l'affaire:
#define is_type_signed(my_type) (((my_type)-1) < 0)
Cette réponse a une variable unitialisée; Cela peut ne pas toujours fonctionner. Besoin de changer en: #define is_type_signed (my_type) (((mon_type (0)) - 1) <0) –
Patrick J: En C++, l'original fonctionne correctement en raison de l'initialisation par défaut. Vous avez raison en C, cependant. – Branan
Comment peut-il y avoir une variable non initialisée lorsque les seules variables sont les temporaires 0 et -1? –
En C++, utilisez 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
Voir http://msdn.microsoft.com/en-us/library/85084kd6(VS.80).aspx.
Pas techniquement une "macro" comme demandé, mais certainement la méthode la plus standard pour un type intégré. –
D'accord, mais les macros doivent être évitées autant que possible en C++ IMO. – ChrisN
D'accord, j'ai voté votre réponse - simplement en la comparant à la réponse acceptée actuellement. –
C++, il y a boost :: is_unsigned < T>. Je suis curieux de savoir pourquoi vous en avez besoin, il y a peu de bonnes raisons à mon humble avis.
Je dois calculer la valeur maximale et la valeur minimale pour une variable de type entier, étant donné son type. – botismarius
Vous pouvez utiliser std :: numeric_limits <> :: max() et std :: numeric_limits <> :: min() pour obtenir les valeurs maximum et minimum d'un type. – ChrisN
Si vous le vouliez, pourquoi ne l'avez-vous pas demandé en premier lieu? –
Votre exigence est pas exactement le meilleur, mais si vous souhaitez pirater ensemble une définition, une option pourrait être:
#define is_numeric_type_signed(typ) ((((typ)0 - (typ)1)<(typ)0) && (((typ)0 - (typ)1) < (typ)1))
Cependant, ce n'est pas considéré agréable ou portable par N'importe quel moyen.
En fait, je me demandais la même chose plus tôt aujourd'hui. Ce qui suit semble fonctionner:
#define is_signed(t) (((t)-1) < 0)
J'ai testé avec:
#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);
}
qui imprime:
int is signed
unsigned int is unsigned
Vous pouvez le faire mieux avec une fonction de modèle, moins macro sale affaire.
template <typename T>
bool IsSignedType()
{
// A lot of assumptions on T here
T instanceAsOne = 1;
if (-instanceAsOne > 0)
{
return true;
}
else
{
return false;
}
}
Forgive la mise en forme ...
J'essayer et voir si cela fonctionne ...
En C++, vous pouvez faire:
bool is_signed = std::numeric_limits<typeof(some_integer_variable)>::is_signed;
numeric_limits est défini dans l'en-tête < limits>.
Il n'y a rien de tel que typeof() en C++. Mais en C++ 11 il y a decltype (variable), ça fait la chose. – mcv
En C, vous ne pouvez pas écrire une macro qui fonctionne sur des types de types entiers non encore inconnus.
En C++, vous pouvez aussi longtemps que votre type est un type entier fondamental ou un typedef d'un type entier fondamental. Voici ce que vous feriez 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 vous voulez une macro alors cela devrait faire l'affaire:
#define IS_SIGNED(T) (((T)-1)<0)
Fondamentalement, jeter -1 à votre type et voir si elle est encore -1 . En C++, vous n'avez pas besoin de macro.Juste #include <limits>
et:
bool my_type_is_signed = std::numeric_limits<my_type>::is_signed;
Althout typeof
est pas C++ juridique pour le moment, vous pouvez utiliser à la place déduction de modèle. Voir l'exemple de code ci-dessous:
#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;
}
Ce code imprimera
1 0 1
Une approche plus "moderne" est d'utiliser type_traits
:
#include <type_traits>
#include <iostream>
int main()
{
std::cout << (std::is_signed<int>::value ? "Signed" : "Unsigned") <<std::endl;
}
C et C++ sont deux langues différentes mais connexes. Vous voulez garder cela à l'esprit - les macros sont une excellente solution en C mais elles sont dangereuses et surtout inutiles en C++. Les macros court-circuitent complètement le contrôle de type en C++, juste pour les démarreurs. –
Il y a certaines choses que vous ne pouvez pas faire sans macros. Quoi qu'il en soit, du code C/C++ est nécessaire si vous voulez faire quelque chose de similaire dans un template C++. – botismarius
Pouvez-vous expliquer ce que "certaines choses" ne peuvent pas faire sans macros? –