vector::size_type

T

t.hall

Is std::vector<T>::size_type guaranteed to be the same type as
std::vector<U>::size_type?

To be more explicit, given
void f(T, U);

and
std::vector<T> vt;
std::vector<U> vu;
which have the same size, can I write

for (std::vector<T>::size_type i = 0; i < vt.size(); ++i) f(vt,
vu);

or should I write

for (std::vector<T>::size_type i = 0; i < vt.size(); ++i) f(vt,
vu[static_cast<std::vector<U>::size_type>(i)]);

Thank you.
 
G

Guest

Is std::vector<T>::size_type guaranteed to be the same type as
std::vector<U>::size_type?

To be more explicit, given
void f(T, U);

and
std::vector<T> vt;
std::vector<U> vu;
which have the same size, can I write

for (std::vector<T>::size_type i = 0; i < vt.size(); ++i) f(vt,
vu);

or should I write

for (std::vector<T>::size_type i = 0; i < vt.size(); ++i) f(vt,
vu[static_cast<std::vector<U>::size_type>(i)]);


I can not find any such guarantee in the standard, but I would be *very*
surprised if they were of different. First, there is no reason to make
them different and second, it is difficult to make them differ for T and
U without having them depend on T and U in some way (which would be the
same as making assumptions about the types T and U). Most implementation
probably uses size_t as std::vector<T>::size_type.
 
K

Kai-Uwe Bux

Is std::vector<T>::size_type guaranteed to be the same type as
std::vector<U>::size_type?

No. (But in practice, they will all be the same as std::size_t.)
To be more explicit, given
void f(T, U);

and
std::vector<T> vt;
std::vector<U> vu;
which have the same size, can I write

for (std::vector<T>::size_type i = 0; i < vt.size(); ++i) f(vt,
vu);


Yes.
or should I write

for (std::vector<T>::size_type i = 0; i < vt.size(); ++i) f(vt,
vu[static_cast<std::vector<U>::size_type>(i)]);


No.


To be more explicit: since you promise that the two vectors have the same
length, std::vector<T>::size_type and std::vector<U>::size_type are large
enough to represent it. Also, both types are guaranteed to be unsigned
integral types. Therefore, the assignment is well-defined.


Best

Kai-Uwe Bux
 
J

Juha Nieminen

Erik said:
Most implementation
probably uses size_t as std::vector<T>::size_type.

Can size_t be safely assumed to be of the same size and
type as std::vector<T>::size_type?
The former is just a lot easier to write, which is why
I'm tempted to use it instead of the latter.

Btw, I have noticed that neither gcc nor VC++ require you
to write it like "std::size_t", but just "size_t" is ok
(without any 'using'). Is this also standard?
 
K

Kai-Uwe Bux

Juha said:
Can size_t be safely assumed to be of the same size and
type as std::vector<T>::size_type?

You can "safely" assume that. But it is not guaranteed. In any case, as long
as the sizes of all your vectors are representable by std::size_t, you
should be fine anyway since then size_type and std::size_t will convert
into one another without changing the values.
The former is just a lot easier to write, which is why
I'm tempted to use it instead of the latter.

Hm, poor form. It is shorter, but it looses meaning. With size_type, you
keep track as to what the variable is supposed to represent.
Btw, I have noticed that neither gcc nor VC++ require you
to write it like "std::size_t", but just "size_t" is ok
(without any 'using'). Is this also standard?

No.


Best

Kai-Uwe Bux
 
P

P.J. Plauger

Kai-Uwe Bux said:
You can "safely" assume that. But it is not guaranteed. In any case, as
long
as the sizes of all your vectors are representable by std::size_t, you
should be fine anyway since then size_type and std::size_t will convert
into one another without changing the values.


Hm, poor form. It is shorter, but it looses meaning. With size_type, you
keep track as to what the variable is supposed to represent.


No.

It will be in C++0X, because it is de facto a widespread practice
in C++98.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
A

Alf P. Steinbach

* Kai-Uwe Bux:
You can "safely" assume that. But it is not guaranteed.

Why not?

As I recall it comes from the allocator, which by default is equipped
with std::size_t as size_type.

Please correct me if wrong.


Cheers,

- Alf
 
K

Kai-Uwe Bux

Alf said:
* Kai-Uwe Bux:

Why not?

As I recall it comes from the allocator, which by default is equipped
with std::size_t as size_type.

Please correct me if wrong.

I can't because you are right. std::vector defines size_type to be
Allocator::size_type (whatever that may be), and for std::allocator it is
guaranteed to be std::size_t. So in order to have a different type for
size_type, one would need to use a different allocator.

I didn't remember :-(


Thanks

Kai-Uwe Bux
 
J

James Kanze

P.J. Plauger said:

[...]
It will be in C++0X, because it is de facto a widespread practice
in C++98.

It's the case in C++ 98 as well if you include <stddef.h>,
rather than <cstddef>.

My own rule to date has been to only use the .h forms of the
C headers, since I know what I'm getting with them. For the
<c...> forms, the standard said one thing, and all
implementations did something else, so I run the risk of
accidentally having code break when (or if) an
implementation does decide to become conform.

Just curious, but with the change in the upcoming standard,
will there be any difference between the .h headers and the
<c...> headers. Or do we just have two different names for
the same thing for historical reasons.
 
T

t.hall

They're both guaranteed to be size_t. Which is what I use;
why obfuscate by suggesting that they might be something
different?

Thank you. I didn't want to obfuscate, I just didn't know...
 
G

Guest

I can't because you are right. std::vector defines size_type to be
Allocator::size_type (whatever that may be), and for std::allocator it is
guaranteed to be std::size_t. So in order to have a different type for
size_type, one would need to use a different allocator.

Where is this specified? When I looked in the standard it said that the
type of std::vector<T>::size_type is implementation dependent with a
reference to 23.1, which only specified that it should be an unsigned
integer type. I only have the C++98 standard, is this perhaps something
that has been amended later and which can be found in C++03?
 
A

Alf P. Steinbach

* Erik Wikström:
Where is this specified? When I looked in the standard it said that the
type of std::vector<T>::size_type is implementation dependent with a
reference to 23.1, which only specified that it should be an unsigned
integer type. I only have the C++98 standard, is this perhaps something
that has been amended later and which can be found in C++03?

Rather it's the other direction, it seems this was something that was
amended /before/ the 98 standard... :)

Then in the direction of removing the nice guaranteed size_type
definitions and replacing them with "implementation defined", except for
basic_string.

<url: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4>.

Short of it: Kai-Uwe originally had it right.

It would be interesting to know the rationale for removing nice
guarantees for size_type everywhere.


Cheers,

- Alf
 
P

P.J. Plauger

P.J. Plauger said:

[...]
It will be in C++0X, because it is de facto a widespread practice
in C++98.

It's the case in C++ 98 as well if you include <stddef.h>,
rather than <cstddef>.

My own rule to date has been to only use the .h forms of the
C headers, since I know what I'm getting with them.

[pjp] Do you? The C++ Standard says that the *.h forms must
declare all names in namespace std, then hoist them to the global
namespace with individual using declarations. A few meticulous
implementations do this, but most leave the *.h forms in their
traditional forms as inherited from older C compilers. So when
you include <stdio.h> you *might* get std::printf and printf,
or you *might* get just printf.


For the
<c...> forms, the standard said one thing, and all
implementations did something else, so I run the risk of
accidentally having code break when (or if) an
implementation does decide to become conform.

[pjp] Not all implementations, but most do. We can configure
our headers to fully conform or work the way our compiler
vendor customers want. Guess which way we choose.

Just curious, but with the change in the upcoming standard,
will there be any difference between the .h headers and the
<c...> headers. Or do we just have two different names for
the same thing for historical reasons.

[pjp] The new rule is:

-- If you want to assuredly declare printf, include <stdio.h>
(but you might also declare std::printf).

-- If you want to assuredly declare std::printf, include
<cstdio> (but you might also declare printf).

That happens to reflect the reality of *all* existing
implementations, so the next C++ Standard will actually
codify existing practice instead of trying to dictate a
practice that most vendors found they could not comply
with.

HTH,

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
K

Kai-Uwe Bux

Erik said:
Where is this specified? When I looked in the standard it said that the
type of std::vector<T>::size_type is implementation dependent with a
reference to 23.1, which only specified that it should be an unsigned
integer type. I only have the C++98 standard, is this perhaps something
that has been amended later and which can be found in C++03?

Argh! I did look into the standard, and I am sure I saw it. But now, I look
up 23.2 and I see std::vector<>::size_type to be implementation defined.
(Maybe, I was looking at std::string before).

Thanks for re-checking.


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Thank you. I didn't want to obfuscate, I just didn't know...

Using vector::size_type is _not_ obfuscation. It's perfectly fine.

Moreover, as it has been discussed elsethread, there is no guarantee that
vector::size_type is std::size_t. [23.2.4/2] lists size_type as
implementation defined.

The next standard will guarantee size_type to be std::size_t.


Best

Kai-Uwe Bux
 
J

James Kanze

P.J. Plauger said:
James Kanze said:
P.J. Plauger said:
[...]
Btw, I have noticed that neither gcc nor VC++ require you
to write it like "std::size_t", but just "size_t" is ok
(without any 'using'). Is this also standard?
No.
It will be in C++0X, because it is de facto a widespread practice
in C++98.
It's the case in C++ 98 as well if you include <stddef.h>,
rather than <cstddef>.
My own rule to date has been to only use the .h forms of the
C headers, since I know what I'm getting with them.
[pjp] Do you?

Probably not, but I feel like I do:). They are, after all, the
C headers, and I know what C gives me. (I guess I think of them
more or less like I think of the Posix headers: something
outside of the language, defined in C.)
The C++ Standard says that the *.h forms must
declare all names in namespace std, then hoist them to the global
namespace with individual using declarations. A few meticulous
implementations do this, but most leave the *.h forms in their
traditional forms as inherited from older C compilers. So when
you include <stdio.h> you *might* get std::printf and printf,
or you *might* get just printf.
[pjp] Not all implementations, but most do. We can configure
our headers to fully conform or work the way our compiler
vendor customers want. Guess which way we choose.

I can imagine.

In practice, I'm used to writing time(NULL), and not
std::time(NULL). So the risk of accident is greater if I choose
the std:: forms---I'm likely to accidentally fall back into my
old habits. If I can count on at least one of my compilers
complaining, immediately, fine; I'll quickly adjust. If I
can't, the error is likely to persist. And while I've not tried
lately, the last time I tried, neither Sun CC nor g++ (under
Solaris) complained. I've long argued that we should also have
Comeau with your library on hand, even if only as a double check
measure, but management here finds that needing to support two
compilers is already one too many.
[pjp] The new rule is:
-- If you want to assuredly declare printf, include <stdio.h>
(but you might also declare std::printf).
-- If you want to assuredly declare std::printf, include
<cstdio> (but you might also declare printf).

In other words, and implementation is allowed to make them the
same, but it could also implement them so that the intersection
is only the macros.
That happens to reflect the reality of *all* existing
implementations, so the next C++ Standard will actually
codify existing practice instead of trying to dictate a
practice that most vendors found they could not comply
with.

I'm not sure I like this. It means that there is still one more
thing that might work with some compilers, but not with others.
If I had my druthers, the committee would just require that both
the declarations with and without std:: be available in both
headers: that shouldn't break any existing code (or at least no
more that the current proposal would break, since that would be
a legal implementation under the current proposal), and would
mean that if it compiles with one implementation, it should
compile with all.
 
J

James Kanze

Kai-Uwe Bux said:
(e-mail address removed) wrote:
Using vector::size_type is _not_ obfuscation. It's perfectly fine.

I think he took my comment too seriously:). Using size_type
does suggest some sort of genericity or dependency on vector,
which of course isn't there unless you're using a vector with a
specialized allocator, or you're writing a template which will
work with a container with a non-standard allocator. (In
template code designed to work with all containers, I do use
size_type.)
Moreover, as it has been discussed elsethread, there is no guarantee that
vector::size_type is std::size_t. [23.2.4/2] lists size_type as
implementation defined.

I didn't see it elsewhere, but the standard definitely requires
vector said:
The next standard will guarantee size_type to be std::size_t.

I don't think there is any change here. I don't know for sure
what the next version of the standard will require, but the
current one definitly requires vector::size_type to be
Allocator::size_type, and for the standard allocator,
allocator::size_type is required to be size_t. The difference
only becomes an issue if you are using custom allocators.
 
A

Alf P. Steinbach

* James Kanze:
I don't think there is any change here. I don't know for sure
what the next version of the standard will require, but the
current one definitly requires vector::size_type to be
Allocator::size_type, and for the standard allocator,
allocator::size_type is required to be size_t. The difference
only becomes an issue if you are using custom allocators.

That's what I thought, but as it turned it out that requirement was
removed for all containers except basic_string prior to the 1998
standardization.

See my article elsethread.

If you have information to the contrary, please share; also, if anyone
has hard information about the rumours about reversing that decision in
C++0x then that would certainly also be nice!


Cheers,

- Alf
 
J

James Kanze

* James Kanze:




That's what I thought, but as it turned it out that requirement was
removed for all containers except basic_string prior to the 1998
standardization.

See my article elsethread.

If you have information to the contrary, please share; also, if anyone
has hard information about the rumours about reversing that decision in
C++0x then that would certainly also be nice!

Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,162
Latest member
GertrudeMa
Top