简体   繁体   English

删除char类型的un- / signed

[英]Remove un-/signedness of char type

I want to specialize a class template for char, short, long and long long. 我想专门针对char,short,long和long long的类模板。 This specializations should also holds good for the signed and unsigned variants of the integral types. 此专长还应适合整数类型的有符号和无符号变体。

I know boost library and std::tr1 / C++0x implements is_signed/is_unsigned and make_signed/make_unsigned type_traits. 我知道boost库和std :: tr1 / C ++ 0x实现了is_signed / is_unsigned和make_signed / make_unsigned type_traits。 But how can I remove any signed specification from the char type (note: the only integral type where signed itype != itype)? 但是,如何从char类型中删除任何带符号的规范(请注意:带符号的itype!= itype的唯一整数类型)?

The "sign-ness" of char is implementation defined. char的“ sign-ness”是实现定义的。 It doesn't have to be able to store negative numbers. 它不必能够存储负数。 In strict standardese, char even is never a signed integer type, even if it can store negative numbers on an implementation. 严格standardese, char甚至是从未有符号整数类型,即使它可以存储上实现负数。 Still, the class template is_signed will report true for char if it can store negative numbers, because that's a useful thing for it to do. 尽管如此,如果类模板is_signed可以存储负数,它将为char报告true ,因为这样做是很有用的。

Anyway, the boost docs say the following about make_unsigned , making it look like you can use it for your purpose. 无论如何,boost文档说了以下有关make_unsigned ,使其看起来像可以用于您的目的。

If T is a unsigned integer type then the same type as T, if T is an signed integer type then the corresponding unsigned type. 如果T是无符号整数类型,则与T相同,如果T是有符号整数类型,则对应的无符号类型。 Otherwise if T is an enumerated or character type (char or wchar_t) then an unsigned integer type with the same width as T 否则,如果T是枚举或字符类型(char或wchar_t),则宽度与T相同的无符号整数类型

Quite manual and hardly any magic going on, but if you want to remove the signed / unsigned from a char , you can use this template: 相当手工,几乎没有什么魔术,但是如果您想从char删除有signed / unsigned ,可以使用以下模板:

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

From the source make_unsigned should still work even on char. 源开始, make_unsigned即使在char上也应该可以使用。 Did you find otherwise? 您是否发现其他情况? If on your platform char is equivalent to unsigned char then it will only have an effect on the explicit signed char type, which is what you want, right? 如果在您的平台上char等同于unsigned char那么它将仅对显式的signed char类型有影响,这是您想要的,对吗?

Okay, I found a quite good looking solution: 好的,我找到了一个很好看的解决方案:

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> */
/* ----------------------------------------------------------------------------------------------------- */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM