当我在windows下编译时,此代码会抛出警告.有解决方案吗
#include<vector>
int main(){
std::vector<int> v;
//...
for (int i = 0; i < v.size(); ++i) { //warning on this line
//...
}
}
Run Code Online (Sandbox Code Playgroud) 我自己确信,在一个项目中,我正在研究有符号整数是大多数情况下的最佳选择,即使其中包含的值永远不会是负数.(更简单的循环反转,更少的错误机会等,特别是对于只能保持0和20之间的值的整数,无论如何.)
出现问题的大多数地方是std :: vector的简单迭代,过去常常是一个数组,之后变为std :: vector.所以这些循环通常如下所示:
for (int i = 0; i < someVector.size(); ++i) { /* do stuff */ }
Run Code Online (Sandbox Code Playgroud)
由于此模式经常使用,因此编译器警告垃圾邮件的数量与签名和未签名类型之间的此比较往往隐藏更多有用的警告.请注意,我们肯定没有带有多个INT_MAX元素的向量,并注意到目前为止我们使用了两种方法来修复编译器警告:
for (unsigned i = 0; i < someVector.size(); ++i) { /*do stuff*/ }
Run Code Online (Sandbox Code Playgroud)
这通常有效但如果循环包含任何代码,如'if(i-1> = 0)......'等,可能会默默地中断.
for (int i = 0; i < static_cast<int>(someVector.size()); ++i) { /*do stuff*/ }
Run Code Online (Sandbox Code Playgroud)
这种变化没有任何副作用,但它确实使循环的可读性降低了很多.(而且它打字更多.)
所以我提出了以下想法:
template <typename T> struct vector : public std::vector<T>
{
typedef std::vector<T> base;
int size() const { return base::size(); }
int max_size() const { return base::max_size(); }
int …Run Code Online (Sandbox Code Playgroud) 关于这个主题已经有一些问题(1、2、3 )。问题是,似乎没有一个明确的答案。有些答案建议( 1 , 2 ),有些答案建议( 1 , 2 )。其他选项包括、、或使用容器或成员类型。size_tptrdiff_tintuint32_tautodecltype.size()size_type
这个问题似乎不适合基于观点,但我认为事实并非如此。仅仅因为尚未就使用哪种类型达成共识,并不意味着不存在客观的答案。这是因为不同的选择不仅美观,而且实际上可以影响代码的行为。
例如,在循环条件中使用符号不匹配的索引变量类型将导致编译器警告,如下所示。此外,使用范围太小的类型可能会导致溢出,在有符号类型的情况下会导致 UB。同时,在某些情况下改变循环计数器类型可能会导致“疯狂的性能偏差”。
我还想找出最流行的(尽管不一定是最好的)创建 for 循环的方法,因此我使用 GitHub *搜索来查找。结果如下:
| 循环型 | GitHub 上的代码结果计数(平均值;“手动”循环 + 基于范围) |
|---|---|
for (int |
15.8m |
for (size_t |
11.6m |
for (auto |
7.5m |
for (uint32_t |
2.3m |
std::for_each |
501k |
for (ptrdiff_t |
98.7k |
for (decltype |
77.5k |
不同循环类型之间的出现次数肯定存在很大差异,但是,似乎没有明显的杰出领导者。
因此,我发布这个问题询问,在 C++ 的 for 循环中索引变量使用的最佳类型是什么,或者应该选择这种类型的规则或条件是什么?
*:GitHub 搜索工具每次都会为“代码结果”(计数)生成不同的结果,因此我对 26 个值进行了平均。由于搜索是基于文本的,因此它包括表单for (int i = 0; i < n; ++i)和的结果for …
我无法正常编译代码.这是我的错误:
警告C4018:'> =':有符号/无符号不匹配
void Player::HasteCap()
{
if (sWorld->getBoolConfig(CONFIG_PLAYER_HASTECAP_ENABLE))
return;
bool hasInstantHasteCap = (GetFloatValue(UNIT_FIELD_BASEATTACKTIME + 0) == 1
|| GetFloatValue(UNIT_FIELD_BASEATTACKTIME + 1) == 1
|| GetFloatValue(UNIT_FIELD_BASEATTACKTIME + 2) == 1
|| GetFloatValue(UNIT_MOD_CAST_SPEED) == 0);
if (m_baseRatingValue[CR_HASTE_MELEE] > sWorld->getIntConfig(CONFIG_PLAYER_HASTECAP_LIMIT))
{
SetFloatValue(UNIT_MOD_CAST_SPEED, 0);
SetFloatValue(UNIT_FIELD_BASEATTACKTIME + BASE_ATTACK, 1);
SetFloatValue(UNIT_FIELD_BASEATTACKTIME + OFF_ATTACK, 1);
SetFloatValue(UNIT_FIELD_BASEATTACKTIME + RANGED_ATTACK, 1);
}
else if (hasInstantHasteCap && m_baseRatingValue[CR_HASTE_MELEE] < sWorld->getIntConfig(CONFIG_PLAYER_HASTECAP_LIMIT))
{
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
SetRegularAttackTime();
ApplyCastTimePercentMod(m_baseRatingValue[CR_HASTE_SPELL] * GetRatingMultiplier(CR_HASTE_SPELL), true);
if (GetShapeshiftForm())
{
SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(GetShapeshiftForm());
if (ssEntry && ssEntry->attackSpeed) …Run Code Online (Sandbox Code Playgroud) 我应该怎么做C++代码中的"签名/无符号不匹配"警告,如下所示:
for (int i = vector.size() - 1; i >= 0; --i) // OK
{
if (i < vector.size() / 2) // warning C4018: '<': signed/unsigned mismatch
// ...
}
Run Code Online (Sandbox Code Playgroud)
(一个人为的例子,但它证明了这个问题.)
如何处理"签名/未签名的不匹配"警告(C4018)?说要size_t用于循环变量,但是这对于终止于0的递减循环不起作用.它在没有警告的情况下编译,但是整数在运行时溢出(或者它是下溢?)并且变为4294967295.
这是代码:
for (int i = 0; i < THE_WORD.length(); ++i)
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:'<':签名/无符号不匹配
THE_WORD初始化如下:
const string THE_WORD;
Run Code Online (Sandbox Code Playgroud)
我正在尝试制作一个"刽子手"程序(现在我自己学习cpp)这是一个for循环的一部分,它循环播放器应该猜测的单词并将字符从星号改为猜测信件.
如果我需要发布更多代码以便回答我的问题,请告诉我.