如果我有代码如
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()
?从根本上说,问题是长度永远不会消极,而无符号类型反映的是最好的。长度不应用a测量 int
。
但除此之外,所有三种解决方案都是相同的。 std::string::size_type
总是 std::size_t
,虽然我会用 static_cast
,在这种情况下,C风格的演员阵容执行相同的演员表。因为你知道返回的长度永远不会消极(顺便说一句,确保这一点;你永远不知道人们会做些什么奇怪的事情),你完全安全,只需要输入类型:
return s2.size() > static_cast<std::size_t>(s1.GetLength());
如果 CString::GetLength
能够 由于某种原因,你应该决定如何将这种转换从负面变为正面。截短?幅度(绝对值)?无论你需要什么。
如果你担心错误,要么做一个明确的检查并抛出异常(取决于你的域,这可能是太昂贵),或使用 assert
。但是,一般来说,您应该信任该文档。
将演员阵容放在自己的功能中,并注释:
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();
}
我会说正确的解决方案是改变签名 CString::getLength()
返回无符号类型。鉴于您按价值获取参数,您可能需要考虑为其提供转换构造函数 CString
拿一个 std::string
(或者你应该改变你的函数的签名来获取它的参数 const&
)。
就个人而言,我认为操作是转换而不是转换,并将其写为:
return std::string::size_type(s1.getLength())
< s2.size();
更改方法CString :: getLength()并返回无符号类型。
尝试这个
return std :: string :: size_type(s1.getLength())
<s2.size();