vector<double>::size_type or vector<int>::size_type

I have a function, in which I need to use a double vector and an int vector, so I need to index both of them, should I define the indexer as vector<double>::size_type index
or vector<int>::size_type index
or just int index?
What's the difference between them?
AFAIK, int will be just fine as long as it's non-negative.
If you want your code to be portable and maintainable, you have to use the size_type defined
in the container to index.

If you want the 99% solution, then currently, at least on gcc, all size_types are nothing more
than typedefs of size_t (which is an unsigned int), so you could use size_t. But, understand
that this could change in the future and your code could stop working or stop compiling.

I see, Thanks.
@jsmith
how do you initialize a size_type? isn't it that you have to give it an int value or long.

the reference says that size_type is an unsigned integral type
http://cplusplus.com/reference/stl/vector/vector/

it does not give more detail on how to initialize or methods on how to give it a value. so what's the big difference between just using int as an index versus using size_type?
The API guarantees you that a vector<>::size_type can be constructed from an int. That does not mean
that size_type is an int; it could be a class with an implicit constructor from int. eg,

1
2
3
4
5
class size_type {
      size_t sz;
  public:
      size_type( int x ) : sz( x ) {}   // Implicit constructor
};

I should also add that the following code generates a compile warning due to comparison of
signed vs. unsigned:

1
2
3
vector<std::string> v;  // assume it has data in it
for( int i = 0; i < v.size(); ++i ) // Compile warning: v.size() returns vector<>::size_type, which is unsigned;  i is signed
    std::cout << v[i] << std::endl;


jsmith wrote:
The API guarantees you that a vector<>::size_type can be constructed from an int. That does not mean
that size_type is an int; it could be a class with an implicit constructor from int.
thanks, that make sense.

So if I want to index a vector I must initialize a size_type giving it an int value, then I must use the size_type I constructed for indexing. I hope I understand it right.
1
2
3
4
5
typedef std::vector< std::string > container_t;

container_t v;  // assume it has data in it
for( container_t::size_type i = 0; i < v.size(); ++i )
    std::cout << v[i] << std::endl;


Is what I'm saying. (I think we're on the same page).
A better solution is to use iterators and not worry about it. I'd also avoid calling the size() or end() function within the loop if I were you.

1
2
3
4
5
for(std::vector<double>::iterator pos(container_t.begin), end(container_t.end());
     pos != end; ++pos)
{
    std::cout << *pos << std::endl;
}
Well wait, is the OP trying to use both containers in the same loop? According to jsmith you'd need two separate iterators or indexers regardless of which way you do it. however I must admit that I have used unsigned integral types for this in the past. I didn't know that it was a big deal.
@jsmith
yay, i understand it right. but still have problems on expressing myself in english lol :p

I'd also avoid calling the size() or end() function within the loop if I were you.
why?
why?


Probably to avoid the generation of the size and end every loop. Although I'm pretty sure size() and end() simply return a private member variable anyway, so it's not actually doing anything extra.
Although I'm pretty sure size() and end() simply return a private member variable anyway, so it's not actually doing anything extra.
That's also what's in my head, i can't think of any other reasons why not use size and end() in loops.
I disagree. Compile and look at the assembly. If you call end() in the loop you will end up seeing a larger number of instructions executing repeatedly than otherwise. Even if it is only an inline function why would you want to execute unnecessary code repeatedly? It is wrong in principle. calling end() in a loop is worse as the iterator is more complex than an integral value returned by size(). I did this recently and the assembly looks very different when you initialize both before the loop. This could depend on the compiler of course.
Last edited on
Topic archived. No new replies allowed.