我使用Oracle API访问数据库,此API有一个函数readBuffer(char * buffer, unsigned int size);
,我无法对其进行任何更改。
我有一个使用此API的类,我的函数签名目前的大小为std::string
和unsigned int
,问题是当我将std::string.size()
传递给我的函数的大小参数,我收到编译器的警告,从size_t
转换为unsigned int
可能会导致数据丢失。
我想知道是否有有效方式将size_t
转换为unsigned int
所以我可以将其传递给我的API并且不会收到编译器的警告?
我理解size_t和搜索谷歌进行此转换的目的会产生很多结果,说“更改函数以获取size_t arg”但我不能更改我的API的签名这种情况。
有什么建议吗?
答案 0 :(得分:17)
是的,编写一个辅助函数来检查这种转换是否有效,否则抛出异常。类似的东西:
unsigned int convert( size_t what )
{
if( what > UINT_MAX ) {
throw SomeReasonableException();
}
return static_cast<unsigned int>( what );
}
答案 1 :(得分:5)
好吧,做一个static_cast<unsigned int>(mystring.size())
。
原因是std::size_t
通常是指针大小,但是有64位平台,int
仍然是32位。在这种情况下,数据丢失的唯一原因是所讨论的字符串长度超过2 ^ 32字节。
如果你知道不会发生这种情况,可以在某处找assert
来捕捉这种情况,并static_cast
让编译器保持沉默。
答案 2 :(得分:4)
static_cast<unsigned int>(str.size());
如果你想成为偏执狂:
if (static_cast<unsigned int>(str.size()) != str.size())
throw ...
答案 3 :(得分:1)
您可以使用
强制转换static_cast<unsigned int>(your_variable)
构造。当然,正确的方法是API接受size_t
...
答案 4 :(得分:1)
此处的风险是size_t
可能大于(unsigned
)int
,因此如果是这种情况,您将无法安全转换。
例如,可以想象int
是32位,而size_t
是64位。我不知道这样的系统/配置,但它可能会发生。
对于大多数“合理”系统,两者都至少为32位,并且(可能)仍然不会发生单个4 GB字符串。
那么你可以投,这可能是有效的,但对于所有可能的系统和角落情况都不会“安全”。