使用size_t的负整数是否安全?

Rob*_*b N 9 c++ unsigned size-t c++11

我刚看到一些像这样的C++代码.它正在使用一个条件来决定是向前还是向后走std::vector.编译器没有抱怨,但我认为size_t是无符号的.这有危险吗?

vector<int> v { 1,2,3,4,5 };    
bool rev = true;

size_t start, end, di;
if (rev) {
    start = v.size()-1;
    end = -1;
    di = -1;
}
else {
    start = 0;
    end = v.size();
    di = 1;
}

for (auto i=start; i!=end; i+=di) {
    cout << v[i] << endl;
}
Run Code Online (Sandbox Code Playgroud)

Che*_*Alf 7

通过size_t这种方式定义使用无符号整数(并且是无符号的),并使用环绕:标准保证了这种行为,而使用有符号整数则不受标准保证.

然而,这是不必要的聪明.

作为一般规则,为了避免由于隐式包装促销到无符号的问题,使用无符号整数用于位级别的东西,使用有符号整数来表示数字.你需要一个有符号整数size_t的地方ptrdiff_t.定义n_items具有签名结果的函数,例如

using Size = ptrdiff_t;

template< class Container >
auto n_items( Container const& c )
    -> Size
{ return end( c ) - begin( c ); }
Run Code Online (Sandbox Code Playgroud)

你已经准备好了,不再是编译器的愚蠢行为.


而不是太聪明的给定代码

vector<int> v { 1,2,3,4,5 };    
bool rev = true;

size_t start, end, di;
if (rev) {
    start = v.size()-1;
    end = -1;
    di = -1;
}
else {
    start = 0;
    end = v.size();
    di = 1;
}

for (auto i=start; i!=end; i+=di) {
    cout << v[i] << endl;
Run Code Online (Sandbox Code Playgroud)

做例如

const vector<int> v { 1,2,3,4,5 };    
const bool reverse = true;  // whatever

for( int i = 0; i < n_items( v );  ++i )
{
    const int j = (reverse? n_items( v ) - i - 1 : i);
    cout << v[j] << endl;
}
Run Code Online (Sandbox Code Playgroud)