我想专门为char,short,long和long long设计一个类模板。这种专业化也适用于整数类型的有符号和无符号变体。
我知道boost库和std :: tr1 / C ++ 0x实现了is_signed / is_unsigned和make_signed / make_unsigned type_traits。但是如何从char类型中删除任何已签名的规范(注意:签名itype!= itype的唯一整数类型)?
答案 0 :(得分:4)
char
的“sign-ness”是实现定义的。它不一定能够存储负数。在严格的标准中,char
甚至从不是有符号整数类型,即使它可以在实现上存储负数。尽管如此,类模板is_signed
会报告true
char
,如果它可以存储负数,因为这对它来说是有用的。
无论如何,提升文档会对make_unsigned
进行以下说明,使其看起来像您可以将它用于您的目的。
如果T是无符号整数类型,则与T的类型相同,如果T是有符号整数类型,则为相应的无符号类型。否则,如果T是枚举或字符类型(char或wchar_t),则无符号整数类型与T具有相同的宽度
答案 1 :(得分:4)
非常手动且几乎没有任何魔法,但如果您要从signed
中删除unsigned
/ char
,则可以使用此模板:
template <typename T>
struct remove_sign_from_char {
typedef T type;
};
template <>
struct remove_sign_from_char<signed char>
{
typedef char type;
};
template <>
struct remove_sign_from_char<unsigned char>
{
typedef char type;
};
int main() {
static_assert( std::is_same< char, remove_sign_from_char<unsigned char>::type >::value );
static_assert( std::is_same< char, remove_sign_from_char<signed char>::type >::value );
static_assert( std::is_same< char, remove_sign_from_char<char>::type >::value );
static_assert( std::is_same< int, remove_sign_from_char<int>::type >::value );
}
答案 2 :(得分:0)
来自the source make_unsigned
即使对char也应该仍然有用。你找不到了吗?如果您的平台上的char
等同于unsigned char
,那么它只对明确的signed char
类型产生影响,这就是您想要的,对吗?
答案 3 :(得分:0)
好的,我找到了一个非常好看的解决方案:
template<typename itype, typename = void> struct my_typedef;
/* ----------------------------------------------------------------------------------------------------- */
template<>
struct my_typedef<char>
{
typedef char type;
typedef signed char signed_type;
typedef unsigned char unsigned_type;
}; /* template<> struct my_typedef<char> */
/* ----------------------------------------------------------------------------------------------------- */
template<>
struct my_typedef<short>
{
typedef short type;
typedef signed short signed_type;
typedef unsigned short unsigned_type;
}; /* template<> struct my_typedef<short> */
/* ----------------------------------------------------------------------------------------------------- */
template<>
struct my_typedef<long>
{
typedef long type;
typedef signed long signed_type;
typedef unsigned long unsigned_type;
}; /* template<> struct my_typedef<long> */
/* ----------------------------------------------------------------------------------------------------- */
template<>
struct my_typedef<long long>
{
typedef long long type;
typedef signed long long signed_type;
typedef unsigned long long unsigned_type;
}; /* template<> struct my_typedef<long long> */
/* ----------------------------------------------------------------------------------------------------- */
template<>
struct my_typedef<signed char>
{
typedef my_typedef<char>::type type;
typedef my_typedef<char>::signed_type signed_type;
typedef my_typedef<char>::unsigned_type unsigned_type;
}; /* template<> struct my_typedef<signed char> */
/* ----------------------------------------------------------------------------------------------------- */
template<typename itype>
struct my_typedef<itype, typename std::enable_if<std::is_unsigned<itype>, void>::type>
{
typedef typename my_typedef<typename std::make_signed<itype>::type>::type type;
typedef typename my_typedef<typename std::make_signed<itype>::type>::type signed_type;
typedef typename my_typedef<typename std::make_signed<itype>::type>::type unsigned_type;
}; /* template<typename> struct my_typedef<signed itype> */
/* ----------------------------------------------------------------------------------------------------- */