问题
Let's make the simplest example possible:
Formulation 1:
std::vector<int> vec;
// add 10E11 elements
for(std::size_t n = 0; n < vec.size(); ++n)
// ...
Formulation 2:
std::vector<int> vec;
// add 10E11 elements
for(std::vector<int>::size_type n = 0; n < vec.size(); ++n)
// ...
Naturally, unsigned int
or any inappropriate data types do not work here and we have to compile x64. My question is: Is there any case in which the first formulation can lead to issues or can we safely always write it in this much shorter notation? I would also be interesting in similar settings if they are trivial to cover (x86, any other container, other applications of size_type
).
回答1:
std::vector
guarantees that pointers are valid iterators for its entire sequence, because vector::data
returns "A pointer such that [data(), data() + size())
is a valid range." That's pointer addition, which is defined over std::ptrdiff_t
, which is the signed version of std::size_t
.
Also, [iterator.requirements.general]/6 applies:
… for integral values
n
and dereferenceable iterator valuesa
and(a + n)
,*(a + n)
is equivalent to*(addressof(*a) + n)
…
It's possible for vector::size_type
to be narrower than std::size_t
, for example 32 bits on a 64-bit system. But it's not something I'd worry about.
回答2:
Although it is the case in all common implementation, the standard makes no guarantee on this. What is guaranteed is that std::vector<T>::size_type
is an implementation defined unsigned integer type.
References:
23.2.1 General container requirements [container.requirements.general]
X::size_type [is a] unsigned integer type
and 23.3.6.1 Class template vector overview [vector.overview] §2
typedef implementation-defined size_type; // see 23.2
回答3:
While std::vector::size_type
is usually std::size_t
, there is no guarantee that it must. It's safer to use
for(std::vector<int>::size_type n = 0; n < vec.size(); ++n)
来源:https://stackoverflow.com/questions/41501798/is-size-t-always-an-alias-for-vectorintsize-type-or-any-other-container