C++:从T转换为无符号T

Not*_*ist 1 c++ templates

我们过度使用模板,我们不能总是告诉手头类型的签名,所以我们需要隐藏最终优化的警告的技术.我有一个简单的ASSERT(condition)宏,如果条件没有评估为真,它会抛出一些东西.

目标是检查T键入count值的范围.我们需要它至少为零,最多为最大值size_t.

template<typename SomeIntegral>
SomeIntegral ZERO()
{
    return SomeIntegral(0);
}

template<typename T>
class C
{
public:
  void f(T count)
  {
    std::vector<std::string> ret;
    ASSERT(count>=ZERO<T>()); // Check #1
    ASSERT(count<std::numeric_limits<size_t>::max()); // Check #2
    ret.reserve(size_t(count)); // Needs check #1 and #2 to succeed.
    // ...
  }
  // ...
};
Run Code Online (Sandbox Code Playgroud)

#1检查在没有警告的情况下编译,但#2检查说comparison between signed and unsigned integer expressions,因为在这种特殊情况下,计数具有签名类型.如果我能ASSERT((unsigned T) count < std::numeric_limits<size_t>::max())以某种方式说或类似......在这种情况下转换为无符号T是安全的,因为我们从#1知道它至少为零.

...或者我可以使用其他编译器不可知的方法?

sta*_*ust 7

我想你可以使用std::make_signedstd::make_unsigned.无论哪个符合需要.


这是一个自定义实现.

namespace internal {

    #define MK_MAKESIGNED(T,V)             \
    template<> struct make_signed<T> {     \
      public:                              \
        typedef V type;                    \
    };                                     


    template<typename T>
    struct make_signed {
        typedef T type;
    };

    MK_MAKESIGNED(unsigned int, signed int);
    MK_MAKESIGNED(unsigned char, signed char);
    // .... can convert anything to anything.

    #undef MK_MAKESIGNED

};


internal::make_signed<unsigned char>::type c;
Run Code Online (Sandbox Code Playgroud)

  • 总有Boost的版本http://www.boost.org/doc/libs/1_53_0/libs/type_traits/doc/html/boost_typetraits/reference/make_signed.html (2认同)