使用无符号整数(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 ); }
只需这样,编译器就不会再提示无意义的警告了。
与太过巧妙的代码不同
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;
做例如
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;
}
std::string::npos
定义为static const size_type npos = -1;
,这基本上是一种类似的技巧。如果要严谨一些,您可能更喜欢:std::vector<int>::size_type start, end, di;
。 - Galikstd::vector<int>::size_type
必须是无符号的,但我认为它可以与std::size_t
的大小不同。虽然我想大多数实现都会将size_type
设为与size_t
相同。 - Galik