如果我有这样的代码
class CString { int GetLength(); };
bool smaller(CString s1, std::string s2) {
return s2.size() > s1.GetLength();
}
对我来说最好的事情是什么?s1.GetLength()
更改为(size_t)c.GetLength()
吗?这将有助于摆脱有关“有符号-无符号不匹配”的编译器警告,并传达我的意图,这是迄今为止最简单的方法。但这可能让人皱眉。 :(
s1.GetLength()
更改为static_cast<size_t>(c.GetLength())
吗?通过“正确”的强制类型转换,可以摆脱警告。
s1.GetLength()
更改为static_cast<std::string::size_type>(c.GetLength())
吗?它非常冗长...这种抽象有实际的好处,还是我应该打破它?
这将有助于使编译器使用
/RTCc
开关(在此我主要关注)进行溢出检查,而以警告为代价。我应该自己设定转换功能吗?使用宏?我应该在运行时还是在编译时检查吗?还有其他想法吗?
编辑:
看起来这个例子确实有点太夸张了...
我显然不是只想谈论
CString::GetLength()
。这种特定的方法当然不是我的大后顾之忧。 :)我担心的是更普遍的情况,当我得到一个从不应该为负的整数,但从理论上讲,可能是由于错误所致。哎呀,我可能正在编写一个执行此操作的方法,以覆盖另一段代码-因此我无法更改签名。即使我不期望,我的代码也肯定有错误。
在这种情况下,我该怎么办?
最佳答案
您可以更改GetLength()
吗?从根本上讲,问题在于长度永远不会为负,而无符号类型则反射(reflect)了最好的长度。长度不应该用int
来衡量。
但是除此之外,您的所有三个解决方案都是相同的。 std::string::size_type
始终是std::size_t
,尽管在这种情况下,我将使用static_cast
,但C样式的强制转换执行相同的强制转换。因为您知道返回的长度永远不会为负(顺便说一句,请确保这一点;您永远不知道人们可能会做些什么奇怪的事情),所以简单地将类型转换为绝对安全:
return s2.size() > static_cast<std::size_t>(s1.GetLength());
如果由于某种原因
CString::GetLength
可以是负数,则由您决定如何将负数转换为正数。截短?幅度(绝对值)?随便你想要什么。如果您担心错误,请进行显式检查并引发异常(具体取决于您的域,这可能会导致成本过高),或者使用
assert
。通常,尽管如此,您应该信任文档。