C++ vector size types
I just started learning C++ and have a question about vectors. The book I'm reading states that if I want to extract the开发者_如何转开发 size of a vector of type double (for example), I should do something like:
vector<double>::size_type vector_size;
vector_size = myVector.size();
Whereas in Java I might do
int vector_size;
vector_size = myVector.size();
My question is, why is there a type named vector::size_type? Why doesn't C++ just use int?
C++ is a language for library writing*, and allowing the author to be as general as possible is one of its key strengths. Rather than prescribing the standard containers to use any particular data type, the more general approach is to decree that each container expose a size_type
member type. This allows for greater flexibility and genericity. For example, consider this generic code:
template <template <typename...> Container, typename T>
void doStuff(const Container<T> & c)
{
typename Container<T>::size_type n = c.size();
// ...
}
This code will work on any container template (that can be instantiated with a single argument), and we don't impose any unnecessary restrictions on the user of our code.
(In practice, most size types will resolve to std::size_t
, which in turn is an unsigned type, usually unsigned int
or unsigned long
-- but why should we have to know that?)
*) I'm not sure what the corresponding statement for Java would be.
Java does not have unsigned integer types, so they have to go with int
.
Contrarily, C++ does and uses them where appropriate (where negative values are nonsensical), the canonical example being the length of something like an array.
The C++ standard says that a container's size_type
is an unsigned integral type, but it doesn't specify which one; one implementation might use unsigned int
and another might use unsigned long
, for example.
C++ isn't "shielded" from platform-specific implementation details as much as Java is. The size_type
alias helps to shield your code from such details, so it'll work properly regardless of what actual type should be used to represent a vector's size.
My personal feeling about this is that it is for a better code safety/readability.
For me int
is a type which conveys no special meaning: it can number apples, bananas, or anything.
size_type
, which is probably a typedef
for size_t
has a stronger meaning: it indicates a size, in bytes.
That is, it is easier to know what a variable mean. Of course, following this rationale, there could be a lot of different types for different units. But a "buffer size" is really a common case so it somehow deserves a dedicated type.
Another aspect is code maintability: if the container suddenly changes its size_type
from say, uint64_t
to unsigned int
for instance, using size_type
you don't have to change it in every source code relying on it.
The book you’re reading states that if you want to extract the size of a vector of type double (for example), you should do something like:
vector<double>::size_type vector_size;
vector_size = myVector.size();
Whereas in Java you might do
int vector_size;
vector_size = myVector.size();
Both are inferior options in C++. The first is extremely verbose and unsafe (mostly due to implicit promotions). The second is verbose and extremely unsafe (due to number range).
In C++, do
ptrdiff_t const vectorSize = myVector.size();
Note that
ptrdiff_t
, from thestddef.h
header, is a signed type that is guaranteed large enough.Initialization is done in the declaration (this is better C++ style).
The same naming convention has been applied to both variables.
In summary, doing the right thing is shorter and safer.
Cheers & hth.,
精彩评论