vector int ::size_type in C++
size_type
is a (static) member type of the type vector<int>
. Usually, it is a typedef
for std::size_t
, which itself is usually a typedef
for unsigned int
or unsigned long long
.
Correct usage of vector int ::size_type
Basically, the above code is 'fine' in the sense that it compiles and does the intended job, as others have said.
When they said the intent was to insert ten int
s in the vector, the int
s are guaranteed positive because of how the loop is formatted, so the unsigned int
will just convert into int
.
However, I don't believe this is good practice as you said - the size type has nothing to do with the type of the elements being inserted - the size type is basically always an unsigned int
. Just using int
or value_type
would obviously make the intent of the code clearer.
C++: vector int ::size_type variable - what is the point of declaring in this way?
size_type
is guaranteed to be large enough for the largest supported vector size, vector::max_size()
. int
is not: on many common platforms, int
has 32 bits, while max_size()
is considerably larger than 231.
If you know the size is (and will always be) a small number like 20, then you can get away with using int
or any other integer type instead of size_type
. If you were to change the program, for example to read the size from the input, then it would go horribly wrong if that value were larger than INT_MAX
; while using size_type
, it would continue working for any value up to max_size()
, which you can easily test for.
How to handle std::vector ... ::size_type being int
Thanks to L. F. for answering the questions.
The real problem, as AMA pointed out, is the use of const
in the type parameter of v_a
. This lead to a compiler-error and ultimately to the warning stated in my question.
The solution was to remove the const-qualifier and fix the dependent types.
Handling int and std::vector::size_type in comparsion
Your code looks a bit too perfect for my taste.
Breaking it down:
const int res = std::stoi(cmdarg);
if (res >= 0 && static_cast<std::vector<MyClass*>::size_type>(res) < this->container.size())
The if-statement for checking below zero is nice. Personally I would write this as:
if (res < 0)
{
std::cerr << "Negative number " << res <<" given for ..., a positive was expected" << std::endl;
return -1;
}
This leads us to the cast:
auto unsigned_res = static_cast<std::vector<MyClass*>::size_type>(res);
However, size_type this vector always size_t
as it uses the std::allocator
. In code review, I would request to change this for readability to:
auto unsigned_res = static_cast<std::size_t>(res);
Finally, you can indeed nicely compare it:
if (unsiged_res < container.size())
// Do something
Note that I mentioned both the comparison and the cast, as this needs to happen in that order. On top of that, you also need some exception handling for when std::stoi
fails, see it's documentation
For more details on how to correctly deal with signed/unsigned, I can recommend this article on ithare.
When should I use vector int ::size_type instead of size_t?
The primary time to use size_type
is in a template. Although std::vector<T>::size_type
is usually size_t
, some_other_container<T>::size_type
might be some other type instead1. One of the few things a user is allowed to add to the std
namespace is a specialization of an existing template for some user defined type. Therefore, std::vector<T>::size_type
for some oddball T
could actually be some type other than size_t
, even though the base template defined in the standard library probably always uses size_t
.
Therefore, if you want to use the correct type for a specific container inside a template that works with that container, you want to use container::size_type
instead of just assuming size_t
.
Note, however, that generic code should rarely work directly with a container. Instead, it should typically work with iterators, so instead of container<T>::size_type
, it would typically use something like std::iterator_traits<WhateverIterator>::difference_type
instead.
- And for some specific
T
,vector<T>::size_type
might be a different type as well--one of the few things you're allowed to put into thestd
namespace is a specialization of an existing class for a user-defined type, so for someT
,vector<T>
could use a completely different container than for most other types. This is typical forvector<bool>
, but possible for other types as well.
difference between size_type and int
vector<double>::size_type
is guaranteed to cover the full range of possible values of the size of a vector<double>
. An int
is not.
Note that vector<double>::size_type
is usually the same as std::size_t
, so in general it would be OK to use the latter. However, custom allocators can result in the a vector with a size_type
different to std::size_t
.
Is `size_t` always an alias for `vector int ::size_type` or any other container type?
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.
Related Topics
Implementing a No-Op Std::Ostream
C++ Compiler Error C2280 "Attempting to Reference a Deleted Function" in Visual Studio 2013 and 2015
Template Instantiation Details of Gcc and Ms Compilers
What Is the First (Int (*)(...))0 Vtable Entry in the Output of G++ -Fdump-Class-Hierarchy
What Is the Meaning of "... ..." Token? I.E. Double Ellipsis Operator on Parameter Pack
Visual Studio 2010's Strange "Warning Lnk4042"
How to Iterate Over a Packed Variadic Template Argument List
"String Could Not Resolved" Error in Eclipse for C++ (Eclipse Can't Resolve Standard Library)
Are Vectors Passed to Functions by Value or by Reference in C++
Order of Evaluation of Elements in List-Initialization
How to Find the Actual Path Found by Bfs
A Base Class Pointer Can Point to a Derived Class Object. Why Is the Vice-Versa Not True
How to Add a Library Path in Cmake
Convert a String to a Date in C++