2013-05-09 71 views
0

我们过度使用模板,并且我们不能始终告诉手头类型的签名,所以我们需要技巧来隐藏最终会优化的警告。我有一个简单的ASSERT(condition)宏,如果条件不是真的,它会抛出一些东西。C++:从T到无符号T的转换

目标是检查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. 
    // ... 
    } 
    // ... 
}; 

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

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

+0

为什么检查agains'的std :: numeric_limits :: MAX()'和'不是的std :: numeric_limits :: MAX()'? – mfontanini 2013-05-09 12:20:40

+0

,因为我将使用该值作为需要'size_t'类型参数的'.reserve()'的参数。你说的那个检查总是如此,除非他们是平等的。 – Notinlist 2013-05-09 12:22:55

回答

6

我认为你可以使用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; 
+0

我非常喜欢它,但它仅来自C++ 11。 http://en.cppreference.com/w/cpp/types/make_unsigned – Notinlist 2013-05-09 12:21:03

+2

总是有Boost的版本http://www.boost.org/doc/libs/1_53_0/libs/type_traits/doc/html/boost_typetraits/reference/ make_signed.html – 2013-05-09 12:23:01

+0

@Notinlist或者如果您只使用常见的整数类型,您可以编写自己的。我将编辑答案。 – stardust 2013-05-09 12:24:23

1

应用static_cast<unsigned long>双方的左手和右手边的表达在你的第二个断言:

ASSERT(static_cast<unsigned long>(count) 
     < static_cast<unsigned long>(std::numeric_limits<size_t>::max())); 

(我假定你的计数是整数,而不是浮 - 如果我错了,走了最大的浮法型)。

+0

如果T大于'unsigned long',该怎么办? – Notinlist 2013-05-09 12:19:46

+0

去'长双'。据我所知,这是最大的标准C++类型 - 请参阅http://www.cplusplus.com/doc/tutorial/variables/ – 2013-05-09 12:22:35