same index, different containers.

A

ALiX

Hi all,

In my code I use different vectors of the same size to hold some data.
At some point I need to iterate through all vectors at the same time.
Now, the question is what type should the index variable have? size_t?
vector<X>::size_type? vector<Y>::size_type? Example code:

--------------------
vector<X> xv;
vector<Y> yv;
vector<Z> zv;

// Fill xv, yv and zv with elements. All three vectors have the same
size.

for (size_t i = 0; i < xv.size(); ++i) {
// Access/modify xv, yv and zv.
}
--------------------

The above code does not appeal to me because xv.size() returns a
vector<X>::size_type and not size_t. And declaring i with type
vector<X>::size_type is not appealing either, since we would then be
using vector<X>::size_type to index into vector<Y>.

I have heard people say that vector<X>::size_type must be of type
size_t for _all_ types X (even when user-supplied allocators). Is this
true? I can't find such a statement in the standard. Even if true for
vectors I don't think it is true for other containers, like deques or
strings. What if I have a deque and a vector that I want to access with
the same index?

Also, using three iterators in the loop seems ugly.

Regards,
ALiX
 
B

Bob Hairgrove

Hi all,

In my code I use different vectors of the same size to hold some data.
At some point I need to iterate through all vectors at the same time.
Now, the question is what type should the index variable have? size_t?
vector<X>::size_type? vector<Y>::size_type? Example code:

--------------------
vector<X> xv;
vector<Y> yv;
vector<Z> zv;

// Fill xv, yv and zv with elements. All three vectors have the same
size.

for (size_t i = 0; i < xv.size(); ++i) {
// Access/modify xv, yv and zv.
}
--------------------

The above code does not appeal to me because xv.size() returns a
vector<X>::size_type and not size_t. And declaring i with type
vector<X>::size_type is not appealing either, since we would then be
using vector<X>::size_type to index into vector<Y>.

I have heard people say that vector<X>::size_type must be of type
size_t for _all_ types X (even when user-supplied allocators). Is this
true? I can't find such a statement in the standard. Even if true for
vectors I don't think it is true for other containers, like deques or
strings. What if I have a deque and a vector that I want to access with
the same index?

Also, using three iterators in the loop seems ugly.

Regards,
ALiX


Just use size_t and don't worry about it. operator[] has to work with
literal index values in all cases, so I don't think you have anything
to worry about as long as it is an unsigned value.
 
B

Ben Pope

ALiX said:
Hi all,

In my code I use different vectors of the same size to hold some data.
At some point I need to iterate through all vectors at the same time.
Now, the question is what type should the index variable have? size_t?
vector<X>::size_type? vector<Y>::size_type? Example code:

--------------------
vector<X> xv;
vector<Y> yv;
vector<Z> zv;

// Fill xv, yv and zv with elements. All three vectors have the same
size.

for (size_t i = 0; i < xv.size(); ++i) {
// Access/modify xv, yv and zv.
}
--------------------


You should ask yourself if, in your situation, X Y and Z form a logical
grouping. You could stick them in a struct and a have a vector<group>
and use vector said:
The above code does not appeal to me because xv.size() returns a
vector<X>::size_type and not size_t. And declaring i with type
vector<X>::size_type is not appealing either, since we would then be
using vector<X>::size_type to index into vector<Y>.

Indeed. Just use size_t, I doubt you'll have any problems in real terms.

Ben Pope
 
A

ALiX

You should ask yourself if, in your situation, X Y and Z form a logical
grouping. You could stick them in a struct and a have a vector<group>
and use vector<group>::size_type.

This did occur to me, but for reasons that are off topic, using indexes
is the preferred way in my case.
Indeed. Just use size_t, I doubt you'll have any problems in real terms.

Probably true. The only problem I can think of, is if vector<X>::size()
returns a number too large to fit in a size_t. However, it would be
less annoying to me if I could find an elegant solution that does not
assume this.

/ALiX
 
A

ALiX

operator[] has to work with
literal index values in all cases, so I don't think you have anything
to worry about as long as it is an unsigned value.

Really? Is this required by the standard? So a value of type unsigned
long could always be safely passed to operator[] (as long as it is not
larger than the number of elements in the vector of course)?

/ALiX
 
B

Bob Hairgrove

Probably true. The only problem I can think of, is if vector<X>::size()
returns a number too large to fit in a size_t. However, it would be
less annoying to me if I could find an elegant solution that does not
assume this.

Would you ever be working with numbers that large? If so, I would
assume that size_t or size_type on such a platform would be typedef'd
to be large enough to handle it.

In reality, a container's actual size would most likely (99.99999% of
the time) impose the more restrictive size constraint.
 
B

Bob Hairgrove

operator[] has to work with
literal index values in all cases, so I don't think you have anything
to worry about as long as it is an unsigned value.

Really? Is this required by the standard? So a value of type unsigned
long could always be safely passed to operator[] (as long as it is not
larger than the number of elements in the vector of course)?

unsigned int is the usual typedef for size_t ... not unsigned long.
 
G

Greg

ALiX said:
operator[] has to work with
literal index values in all cases, so I don't think you have anything
to worry about as long as it is an unsigned value.

Really? Is this required by the standard? So a value of type unsigned
long could always be safely passed to operator[] (as long as it is not
larger than the number of elements in the vector of course)?

Yes. You could also pass a char, short, float, double or long double
(among others) as an index (and in the upcoming C++ language revision,
a long long, or unsigned long long index will work as well). In short,
you can pass any numeric type just as long as the value of the index
(after any conversion) is = 0 and < the value returned by the
container's size() method.

A numeric type that is passed as a parameter in any function call will
simply convert to the numeric type declared for that parameter.
Ordinarily this conversion could lose information - but because the
value passed to the container's operator[] must be less than the value
size() returns, and because size() returns the same type that
operator[] accepts, it is clear that no valid index value passed to a
container's operator[] would ever be truncated.

Greg
 
G

Greg

ALiX said:
operator[] has to work with
literal index values in all cases, so I don't think you have anything
to worry about as long as it is an unsigned value.

Really? Is this required by the standard? So a value of type unsigned
long could always be safely passed to operator[] (as long as it is not
larger than the number of elements in the vector of course)?

/ALiX

Yes. You could also pass a char, short, float, double or long double
(among others) as an index (and in the upcoming C++ language revision,
a long long, or unsigned long long index will work as well). In short,
you can pass any numeric type just as long as the value of the index
(after any conversion) is >= 0 and < the value returned by the
container's size() method.

A numeric type that is passed as a parameter in any function call will
simply convert to the numeric type declared for that parameter.
Ordinarily this conversion could lose information - but because the
value passed to the container's operator[] must be less than the value
size() returns, and because size() returns the same type that
operator[] accepts, it is clear that no valid index value passed to a
container's operator[] would ever be truncated.

Greg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top