11

如果我有诸如

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()。这种特殊的方法当然不是我的大担心。:) 我担心的是更一般的情况,即当我得到一个不应该为负的整数时,但理论上可能是由于错误。

哎呀,我可能正在编写一个这样做的方法,以覆盖另一段代码——所以我不能更改签名。我的代码肯定有错误,即使我没想到。

在这种情况下,我该怎么办?

4

4 回答 4

6

你能改变GetLength()吗?从根本上说,问题是长度永远不是负数,无符号类型反映了最好的情况。长度不应该用int.

但除此之外,您的所有三个解决方案都是相同的。std::string::size_type总是std::size_t,虽然我会使用 a static_cast,但在这种情况下,C 风格的演员表执行相同的演员表。因为你知道返回的长度永远不会是负数(顺便说一句,确保这一点;你永远不知道人们可能会做些什么奇怪的事情),你只需转换类型就完全安全了:

return s2.size() > static_cast<std::size_t>(s1.GetLength());

如果出于某种原因CString::GetLength 可能是负数,那么由您决定如何将这种转换从负数转换为正数。截短?幅度(绝对值)?无论你需要什么。


如果您担心错误,请进行显式检查并抛出异常(取决于您的域,这可能成本太高),或者使用assert. 但是,通常,您应该信任文档。

于 2012-04-05T08:58:11.747 回答
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();
}
于 2012-04-05T09:18:08.470 回答
2

我想说正确的解决方案是更改签名CString::getLength()以返回无符号类型。鉴于您正在按值传递参数,您可能需要考虑提供一个转换构造函数来CString获取 a std::string(否则您可能应该更改函数的签名以获取其参数const&)。

就我个人而言,我认为该操作是转换而不是强制转换并将其编写为:

return std::string::size_type(s1.getLength())
    < s2.size();
于 2012-04-05T09:06:41.100 回答
0

更改方法 CString::getLength() 并返回无符号类型。

试试这个

返回 std::string::size_type(s1.getLength()) < s2.size();

于 2012-04-05T11:33:10.223 回答