有符号和无符号之间的比较。是static_cast唯一的解决方案吗?

时间:2018-11-29 18:09:46

标签: c++ c++11 implicit-conversion static-cast

我使用使用int来存储大小的第三方容器。我还使用了使用size_t来存储大小的stl容器。

我经常在我的代码中必须在同一个循环中同时使用两者,例如:

// vec is std::vector
// list is the third party container
assert(vec.size() == list.size()); // warning
for(size_t i = 0; i < vec.size(); i++)
{
    vec[i] = list[i]; // warning
}

所以要解决这个问题,我必须要么执行函数样式转换,要么被告知是变相的C样式转换。

// vec is std::vector
// list is the third party container
assert(int(vec.size()) == list.size());
for(size_t i = 0; i < vec.size(); i++)
{
    vec[i] = list[int(i)];
}

或者我可以做每个人都推荐的更丑陋的解决方案。静态投射。

// vec is std::vector
// list is the third party container
assert(static_cast<int>(vec.size()) == list.size());
for(size_t i = 0; i < vec.size(); i++)
{
    vec[i] = list[static_cast<int>(i)];
}

我真的不想static_cast

  • 在这种特定情况下进行隐式转换会很危险吗?
  • 在我看来,函数样式还可以吗?
  • 如果static_cast确实是唯一安全的解决方案。我应该将int投射到size_t还是size_t投射到int

谢谢。

1 个答案:

答案 0 :(得分:2)

如果其中一个参数是无符号的,二进制运算符(此处为operator==)会将有符号的整数转换为无符号。一个有符号的负整数变成一个很大的正整数。

容器元素计数不得为负,以免破坏最少惊奇的原则。因此,隐式转换必须是安全的。但是请务必检查int size() const的实现/文档。

您可能希望保留隐式转换的语义,并使用as_unsigned函数来避免强制转换并更好地传达意图:

#include <type_traits>

template<class T>
inline typename std::make_unsigned<T>::type as_unsigned(T a) {
    return static_cast<typename std::make_unsigned<T>::type>(a);
}

然后:

assert(vec.size() == as_unsigned(list.size()));