【问题标题】:Remove un-/signedness of char type删除 char 类型的 un-/signed
【发布时间】:2011-07-02 14:28:36
【问题描述】:

我想专门为 char、short、long 和 long long 编写一个类模板。这种特化也应该适用于整数类型的有符号和无符号变体。

我知道 boost 库和 std::tr1 / C++0x 实现了 is_signed/is_unsigned 和 make_signed/make_unsigned type_traits。但是如何从 char 类型中删除任何带符号的规范(注意:签名 itype 的唯一整数类型!= itype)?

【问题讨论】:

标签: c++ typetraits


【解决方案1】:

好的,我找到了一个相当不错的解决方案:

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

【讨论】:

  • 我不太明白你在这里要做什么......最后一个模板专业化基本上是说std::is_same&lt; unsigned int, my_typedef&lt; unsigned int &gt;::unsigned &gt;::value == false?如果这是故意的,那么它至少是一种误导:my_typedef&lt;...&gt;::unsigned 是有符号类型。
【解决方案2】:

相当手动,几乎没有任何魔法,但如果你想从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 );
}

【讨论】:

    【解决方案3】:

    来自the source make_unsigned 即使在字符上也应该仍然可以工作。你有没有发现其他的?如果在您的平台上char 等同于unsigned char,那么它只会对显式signed char 类型产生影响,这正是您想要的,对吧?

    【讨论】:

      【解决方案4】:

      char 的“符号”是实现定义的。它不必能够存储负数。在严格的标准中,char 甚至 从不 是有符号整数类型,即使它可以在实现中存储负数。尽管如此,类模板is_signed 将报告truechar 如果它可以存储负数,因为这对它来说是一件有用的事情。

      无论如何,boost 文档对make_unsigned 说了以下内容,看起来您可以将其用于您的目的。

      如果 T 是无符号整数类型则与 T 相同类型,如果 T 是有符号整数类型则对应无符号类型。否则,如果 T 是枚举或字符类型(char 或 wchar_t),则为与 T 宽度相同的无符号整数类型

      【讨论】:

      • 不过,编写一个模板非常简单,该模板将通过对这些特定类型使用两个特化来从 char 类型中删除 signedunsigned。还是我在这里遗漏了什么?
      • @David 我无法真正理解这个问题,所以像“我想将 char 更改为 unsigned char,以删除任何有符号性”一样阅读它是我解释它的方式。当然,你对这个问题的解读看起来也很合理。
      • 很高兴您决定取消删除帖子,这里的信息——无论正确解释是一种还是另一种——实际上都很有价值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 2011-07-02
      • 2012-01-13
      相关资源
      最近更新 更多