如果我有
等代码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()
。这种特殊方法当然不是我的一大担心。 :)我担心的是更多一般的情况,当我得到一个永远不会假设为负的整数,但可能> em>理论上是由于错误。
哎呀,我可能正在编写这样做的方法,以便覆盖另一段代码 - 所以我无法更改签名。而且我的代码肯定会有错误,即使我没想到它。
在这种情况下,我该怎么办?
答案 0 :(得分:6)
您可以更改GetLength()
吗?从根本上说,问题是长度永远不会消极,而无符号类型反映的是最好的。长度不应使用int
来衡量。
但除此之外,所有三种解决方案都是相同的。 std::string::size_type
总是std::size_t
,而我会使用static_cast
,在这种情况下,C风格的强制转换会执行相同的强制转换。因为你知道返回的长度永远不会消极(顺便说一句,确保这一点;你永远不知道人们会做些什么奇怪的事情),你完全安全,只需输入类型:
return s2.size() > static_cast<std::size_t>(s1.GetLength());
如果CString::GetLength
可能由于某种原因,那么由您来决定如何将该转化从负转为正。截短?幅度(绝对值)?无论你需要什么。
如果您担心错误,请进行明确检查并抛出异常(取决于您的域名,这可能代价太高),或使用assert
。但是,一般来说,您应该信任该文档。
答案 1 :(得分:4)
将演员阵容放在自己的函数中,并带有注释:
std::string::size_type size(const CString& mfcString)
{
// CString::GetLength is always non-negative
// http://msdn.microsoft.com/en-us/library/aa300471(v=vs.60).aspx
return static_cast<std::string::size_type>(mfcString.GetLength());
}
然后您的代码将是:
bool smaller(const CString& s1, const std::string& s2)
{
return size(s1) < s2.size();
}
答案 2 :(得分:2)
我认为正确的解决方案是更改CString::getLength()
的签名以返回无符号类型。鉴于您按价值获取参数,您可能需要考虑为CString
提供std::string
的转换构造函数(或者您应该更改函数的签名以使其参数{{1} }})。
就我个人而言,我认为该操作是转换而不是转换,并将其写为:
const&
答案 3 :(得分:0)
更改方法CString :: getLength()并返回无符号类型。
试试这个
return std :: string :: size_type(s1.getLength()) &LT; s2.size();