C++ vector size types

2019-03-24 09:20发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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.



回答5:

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 the stddef.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.,



标签: c++ vector int