C++ 有符号和无符号之间的比较。静态_cast是唯一的解决方案吗?

C++ 有符号和无符号之间的比较。静态_cast是唯一的解决方案吗?,c++,c++11,implicit-conversion,static-cast,C++,C++11,Implicit Conversion,Static Cast,我使用使用int存储大小的第三方容器。我还使用stl容器,它使用size\u t来存储大小 在我的代码中,我经常必须在同一个循环中使用这两种方法,例如: // 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]; //

我使用使用
int
存储大小的第三方容器。我还使用stl容器,它使用
size\u t
来存储大小

在我的代码中,我经常必须在同一个循环中使用这两种方法,例如:

// 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
}
//vec是std::vector
//列表是第三方容器
断言(vec.size()==list.size());//警告
对于(size_t i=0;i
所以要解决这个问题,我必须要么做函数式转换,我被告知这是伪装的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是std::vector
//列表是第三方容器
断言(int(vec.size())==list.size());
对于(size_t i=0;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)];
}
//vec是std::vector
//列表是第三方容器
断言(static_cast(vec.size())==list.size());
对于(size_t i=0;i
我真的不想
static\u cast

  • 在这种特殊情况下,隐式转换会很危险吗
  • 在我的情况下,函数样式可以吗
  • 如果静态强制转换确实是唯一安全的解决方案。我应该将
    int
    转换为
    size\u t
    还是将
    size\u t
    转换为
    int
谢谢。

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

容器元素计数不得为负数,以避免违反最小意外原则。因此,隐式转换必须是安全的。但是一定要检查
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);
}

在您的示例中,static_cast和C-style cast在功能上没有区别,它们都做相同的事情。不使用static_cast的建议来自这样一个事实,即它是一个糟糕的肌肉记忆,显式cast使代码更容易理解。至于演员的方向,你的平台上允许的
size\u t
vs
int
范围是多少?@SergeyA sizeof(int)=4。尺寸f(尺寸t)=8@serg另外,因为若size返回指针或可转换为指针的类型,则c样式可以从指针重新解释中获得int类型转换。这里不太可能?对这会发生吗?是的。那个函数不会仍然给出警告吗?@AdamZahran-Nope。好吧,所以它不会用-Wall发出警告,但它会用-Wsign转换发出警告。我应该不关心它,或者禁用/抑制它吗?@AdamZahran
as_unsigned
编译时没有警告,没有强制转换。试试看。@AdamZahran
inline
不是函数模板所必需的,你说得对。
assert(vec.size() == as_unsigned(list.size()));