1

有时我会收到从较长类型转换为较小类型的警告,例如:

void f( unsigned short i ) // f - accept any numeric type
                           // smaller than std::vector<>::size_type
{}

std::vector < some_type > v;
..
f ( v.size() );

通常我使用下一个解决方案之一:

assert( v.size() <= std::numeric_limits< unsigned short >::max() );
f( static_cast< unsigned short >( v.size() ) );

或者

f( boost::numeric_cast<  unsigned short >( v.size() ) );

但是在我目前的工作中没有使用提升,并且从上个月开始断言是不允许的。

您还知道哪些其他安全方法可以抑制此警告?
任何已知方式的陷阱?

PS: 并非总是可以更改 f 的签名,有时也确实应该接受小的数字类型。

编辑: 我想让转换尽可能安全。

4

4 回答 4

7

为什么要先投?向量的大小通常是无符号整数。如果可能的话,我会说更新函数签名。警告并不是要被压制,而是要解决。

于 2009-04-04T13:05:44.297 回答
3

处理此问题的唯一安全方法是确保您在运行时不会丢失转换。断言代码仅在调试构建期间有效,并允许零售构建中的转换损失。转换损失很糟糕,因为它会传递一个完全不正确的向量大小。

您真正需要的是一种机制来防止您造成数据丢失。我建议使用像 SafeInt 这样的类。这将通过引发异常来防止上溢或下溢的转换。

SafeInt<size_t> size = v.size();
f((unsigned short)size);  // Throws if size can't fit in an unsigned short

SafeInt: http: //www.codeplex.com/SafeInt

于 2009-04-04T13:27:01.127 回答
2

我现在再次重复我的口头禅如果您的代码包含演员表,则代码或设计可能有问题,您应该检查两者以消除演员表。

顺便说一句,我上次发布时,您对此表示赞同!

于 2009-04-04T13:13:33.717 回答
2

由于 size() 通常返回一个无符号整数,因此将其类型转换为有符号整数应该是非常安全的。

f(static_cast<expected-type>(v.size()));

否则,如果可能,请更改函数签名。

于 2009-04-04T13:14:53.527 回答