9

我正在使用 Oracle API 访问数据库,并且该 API 具有readBuffer(char * buffer, unsigned int size);我无法对其进行任何更改的功能。

我有一个使用此 API 的类,并且我的函数的签名当前采用 astd::string和 anunsigned int作为大小,问题是当我传递std::string.size()给函数的 size 参数时,我从编译器收到警告,表明从size_tto转换unsigned int可以导致数据丢失。

我想知道是否有一种有效的方法可以将 转换size_t为 anunsigned int以便我可以将其传递给我的 API 而不会从编译器收到警告?

我了解 size_t 的目的,并且在谷歌上搜索这种转换会出现很多结果,上面写着“更改函数以采用 size_t arg”,但在这种情况下我不能更改我的 API 的签名。

有什么建议么?

4

5 回答 5

20

是的,编写一个辅助函数来检查这种转换是否有效,否则抛出异常。就像是:

unsigned int convert( size_t what )
{
    if( what > UINT_MAX ) {
       throw SomeReasonableException();
    }
    return static_cast<unsigned int>( what );
}
于 2011-04-19T10:06:50.407 回答
5

好吧,做一个static_cast<unsigned int>(mystring.size())

原因是std::size_t通常是指针大小,但是在 64 位平台上,anint仍然是 32 位。在这种情况下,数据丢失的唯一原因是相关字符串的长度超过 2^32 字节。

如果您知道这不会发生,请放置一个assert地方来捕捉这种情况并static_cast让编译器保持沉默。

于 2011-04-19T10:07:03.947 回答
4
static_cast<unsigned int>(str.size());

如果你想偏执:

if (static_cast<unsigned int>(str.size()) != str.size()) 
  throw ...
于 2011-04-19T10:07:04.087 回答
1

您可以使用强制转换

static_cast<unsigned int>(your_variable)

构造。当然,正确的方法是让 API 接受size_t......

于 2011-04-19T10:06:41.660 回答
1

这里的风险size_t可能大于 ( unsigned) int,因此如果是这种情况,您将无法安全地转换。

例如,可以想象的int是 32 位,而size_t64 位。我不知道这样的系统/配置,但它可能会发生。

对于大多数“合理”的系统,两者都至少为 32 位,并且仍然(可能)不太可能出现单个 4 GB 字符串。

因此,您可以直接转换,这将是有效的,但对于所有可能的系统和极端情况来说,它并不是“安全的”。

于 2011-04-19T10:06:42.123 回答