C++ 如何正确投法?(或者我应该这样做吗?)
如果我有这样的代码C++ 如何正确投法?(或者我应该这样做吗?),c++,visual-c++,casting,integer,C++,Visual C++,Casting,Integer,如果我有这样的代码 class CString { int GetLength(); }; bool smaller(CString s1, std::string s2) { return s2.size() > s1.GetLength(); } 对我来说最好的事情是什么 将s1.GetLength()更改为(大小)c.GetLength()? 这将有助于消除编译器关于“有符号-无符号不匹配”的警告,并传达我的强制转换意图,这是迄今为止最简单的方法。但这可能是不赞成的(
class CString { int GetLength(); };
bool smaller(CString s1, std::string s2) {
return s2.size() > s1.GetLength();
}
对我来说最好的事情是什么
- 将
更改为s1.GetLength()
?(大小)c.GetLength()
这将有助于消除编译器关于“有符号-无符号不匹配”的警告,并传达我的强制转换意图,这是迄今为止最简单的方法。但这可能是不赞成的( - 将
更改为s1.GetLength()
?static_cast(c.GetLength())
这将有助于摆脱警告,使用“正确”类型的演员阵容 - 将
更改为s1.GetLength()
?static_cast(c.GetLength())
它非常冗长……这种抽象有实际的好处吗,或者我应该打破它吗 - 保持原样?
这将有助于编译器使用
开关执行溢出检查(这里我主要关心的是),而不是警告/RTCc
- 做点别的吗?
我应该制作自己的强制转换函数吗?使用宏吗?我应该在运行时和编译时检查吗?还有其他想法吗
CString::GetLength()
。这个特殊的方法肯定不是我所担心的。:)我担心的是更一般的情况,当我得到一个整数时,它永远不应该是负的,但理论上可能是负的,因为有bug
见鬼,我可能正在编写一个这样做的方法,以便重写另一段代码——因此我无法更改签名。我的代码肯定会有bug,尽管我没有预料到
在这种情况下,我应该怎么做?您可以更改
GetLength()
?从根本上说,问题在于长度永远不会为负,而无符号类型反映了最好的结果。长度不应使用int
来测量
但除此之外,您的三种解决方案都是相同的std::string::size_type
始终是std::size_t
,虽然我会使用static_cast
,但在这种情况下,C样式的cast执行相同的cast。因为您知道返回的长度永远不会为负(顺便说一句,请确保这一点;您永远不知道人们可能会做什么奇怪的事情),所以您完全可以安全地转换类型:
return s2.size() > static_cast<std::size_t>(s1.GetLength());
返回s2.size()>static_cast(s1.GetLength());
如果由于某种原因,CString::GetLength
可以是负数,那么由您决定如何将负数转换为正数。截断震级(绝对值)?你需要什么都行
如果您担心bug,可以执行显式检查并抛出异常(取决于您的域,这可能代价太高),或者使用
断言。不过,一般来说,您应该信任文档。我认为正确的解决方案是更改CString::getLength()
的签名以返回无符号类型。鉴于您是Takangu您的值的参数,您可能需要考虑为<代码> cString < /Cord>提供转换构造函数,使用<代码> STD::String (OrHeWrice,您应该更改您的函数的签名,以通过代码> const和<代码>来获取它的参数)。
个人而言,我认为操作是转换而不是铸造,并将其写成:
return std::string::size_type(s1.getLength())
< s2.size();
返回std::string::size\u类型(s1.getLength())
将强制转换放在自己的函数中,并添加注释:
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());
}
std::string::size\u类型size(const-CString和mfcString)
{
//CString::GetLength始终为非负
// http://msdn.microsoft.com/en-us/library/aa300471(v=vs.60).aspx
返回static_cast(mfcString.GetLength());
}
那么您的代码将是:
bool smaller(const CString& s1, const std::string& s2)
{
return size(s1) < s2.size();
}
bool较小(常数CString&s1,常数std::string&s2)
{
返回大小(s1)
更改方法CString::getLength()并返回无符号类型
试试这个
返回std::string::size\u类型(s1.getLength())
我肯定会远离最后一个,可能会选择第一个。其他人似乎对此很详细。你的意思是s2.size()
?更改GetLength()
以返回size\u t
?在这种情况下GetLength()
返回负值有意义吗?@Default:Ah我有,输入错误;谢谢。你是说我应该完全忽略/RTCc
的好处(在调试模式下)?这似乎很有帮助。。。(不,我不能更改它——它在预先编写的库中,例如ATL/WTL/MFC。)我假设CString
来自Windows MFC。@Mehrdad:如果检查很重要,我会自己添加它,而不依赖特定的编译器功能。如果GetLength()
从来都不是负数,那么请随意转换。不会有任何数据丢失。@GManNickG:这只是帮助我找到bug的“重要”,而不是“重要”,因为如果代码已经正确,这是应该发生的事情。@Mehrdad:我真的不明白。如果GetLength()
从不为负,则强制转换为相同(或更大)位大小的无符号类型不会导致数据丢失<代码>标准::大小\u t
肯定与int
一样大,因此您可以完全安全地进行转换,无需任何检查。转换是一种转换。你只是改变了cast符号,它们是。我很清楚T(x)
和static\u cast(x)
相当于编译器。然而,有意识的符号可以向人类读者传达信息:在其他地方,例如向下转换(在相应的隐式转换之后),我使用static\u cast(x)
提请注意,这不仅仅是修补其他隐式转换。在我看来,这是迄今为止最好的答案。当处理一个粗糙的API时,不要用黑客乱扔你的代码。相反,提供wr