Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确投法?(或者我应该这样做吗?)_C++_Visual C++_Casting_Integer - Fatal编程技术网

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