Correct usage of std::vector?

M

mlt

I need to use a std::vector to specify a matrix of integers (my code must
not use std::boost). But is:

std::vector<std::vector<int>> vec(1,1);
vec[0][0] = 34;

an example of correct use?
 
K

Kai-Uwe Bux

mlt said:
I need to use a std::vector to specify a matrix of integers (my code must
not use std::boost). But is:

std::vector<std::vector<int>> vec(1,1);
vec[0][0] = 34;

an example of correct use?

No:

a) std::vector<std::vector<int>> is currently a syntax error because of
the ">>" token. Make that

std::vector< std::vector< int > >

b) The constructor arguments should read:

std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );

In general,

std::vector< std::vector< int > >
vec ( rows, std::vector< int >(cols) );

should do what you want.


Best

Kai-Uwe Bux
 
M

mlt

Kai-Uwe Bux said:
mlt said:
I need to use a std::vector to specify a matrix of integers (my code must
not use std::boost). But is:

std::vector<std::vector<int>> vec(1,1);
vec[0][0] = 34;

an example of correct use?

No:

a) std::vector<std::vector<int>> is currently a syntax error because of
the ">>" token. Make that

std::vector< std::vector< int > >

b) The constructor arguments should read:

std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );

In general,

std::vector< std::vector< int > >
vec ( rows, std::vector< int >(cols) );

should do what you want.


Best

Kai-Uwe Bux


Ok I see you point but currently:

std::vector<std::vector<int>> vec(1,1);

does not give any compiler error (Using Visual Studio 2008) and when running
the app I also get the correct behaviour. So I don't think its necessary to
do:

std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );

when using Visual Studio at least (have not tested on unix yet).
 
K

Kai-Uwe Bux

mlt said:
Kai-Uwe Bux said:
mlt said:
I need to use a std::vector to specify a matrix of integers (my code
must not use std::boost). But is:

std::vector<std::vector<int>> vec(1,1);
vec[0][0] = 34;

an example of correct use?

No:

a) std::vector<std::vector<int>> is currently a syntax error because of
the ">>" token. Make that

std::vector< std::vector< int > >

b) The constructor arguments should read:

std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );

In general,

std::vector< std::vector< int > >
vec ( rows, std::vector< int >(cols) );

should do what you want.


Best

Kai-Uwe Bux


Ok I see you point but currently:

std::vector<std::vector<int>> vec(1,1);

does not give any compiler error (Using Visual Studio 2008) and when
running the app I also get the correct behaviour. So I don't think its
necessary to do:

std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );

when using Visual Studio at least (have not tested on unix yet).

Well, it does not work with g++.

Presumably, whether you get an error from

std::vector<std::vector<int>> vec(1,1);

will depend on the STL that your vendor uses. The constructor that gets
invoked it

std::vector<T> ( size_type n, T const & t )

for T = std::vector<int>. Now, since std::vector<int> in turn can be
initialized from a size_type, a conversion of the argument can take place.
I am not sure whether g++ is at fault for not doing that: the constructor
needed for the conversion is marked as "explicit" in the standard.
Therefore, I think, no automatic conversion should take place.


Best

Kai-Uwe Bux
 
J

James Kanze

mlt wrote:
Kai-Uwe Bux said:
mlt wrote:
I need to use a std::vector to specify a matrix of
integers (my code must not use std::boost). But is:
std::vector<std::vector<int>> vec(1,1);
vec[0][0] = 34;
an example of correct use?
No:
a) std::vector<std::vector<int>> is currently a syntax
error because of the ">>" token. Make that
std::vector< std::vector< int > >
b) The constructor arguments should read:
std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );
In general,
std::vector< std::vector< int > >
vec ( rows, std::vector< int >(cols) );
should do what you want.
Ok I see you point but currently:
std::vector<std::vector<int>> vec(1,1);
does not give any compiler error (Using Visual Studio 2008)
and when running the app I also get the correct behaviour.
So I don't think its necessary to do:
std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );
when using Visual Studio at least (have not tested on unix yet).
Well, it does not work with g++.
Presumably, whether you get an error from
std::vector<std::vector<int>> vec(1,1);
will depend on the STL that your vendor uses.

Formally, the standard requires it to work. Whether this is
intentional or not is another question---it may be an error in
the standard. (On the other hand: the standard has guaranteed
it, so it's rather hard to say that in fact, it is illegal, even
if the guarantee wasn't intentional.)
The constructor that gets invoked it
std::vector<T> ( size_type n, T const & t )

No. The constructor which gets invoked is an instantiation of:

template< InputIterator >
vector::vector( InputIterator begin, InputIterator end ) ;

Instantiated with InputIterator == int, this is an exact match;
the one you propose requires a conversion of int to size_t.
for T = std::vector<int>. Now, since std::vector<int> in turn
can be initialized from a size_type, a conversion of the
argument can take place. I am not sure whether g++ is at
fault for not doing that: the constructor needed for the
conversion is marked as "explicit" in the standard.
Therefore, I think, no automatic conversion should take place.

The standard says (§23.1.1/9) that if in the above template
constructor, InputIterator has an integral type (and it does
here), it shall have the same effect as:

std::vector( static_cast< size_type >( begin ),
static_cast< value_type >( end ) )

Those static_cast are explicit conversions.

This may not be what was desired, but it is definitly what the
current standard requires (and a quick glance at the CD shows
no changes here).
 
C

coal

mlt said:
mlt wrote:
I need to use a std::vector to specify a matrix of
integers (my code must not use std::boost). But is:
   std::vector<std::vector<int>> vec(1,1);
   vec[0][0] = 34;
an example of correct use?
No:
a) std::vector<std::vector<int>> is currently a syntax
error because of the ">>" token. Make that
 std::vector< std::vector< int > >
b) The constructor arguments should read:
 std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );
In general,
 std::vector< std::vector< int > >
   vec ( rows, std::vector< int >(cols) );
should do what you want.
Ok I see you point but currently:
   std::vector<std::vector<int>> vec(1,1);
does not give any compiler error (Using Visual Studio 2008)
and when running the app I also get the correct behaviour.
So I don't think its necessary to do:
    std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );
when using Visual Studio at least (have not tested on unix yet).
Well, it does not work with g++.
Presumably, whether you get an error from
  std::vector<std::vector<int>> vec(1,1);
will depend on the STL that your vendor uses.

Formally, the standard requires it to work.  Whether this is
intentional or not is another question---it may be an error in
the standard.  (On the other hand: the standard has guaranteed
it, so it's rather hard to say that in fact, it is illegal, even
if the guarantee wasn't intentional.)
The constructor that gets invoked it
  std::vector<T> ( size_type n, T const & t )

No.  The constructor which gets invoked is an instantiation of:

    template< InputIterator >
    vector::vector( InputIterator begin, InputIterator end ) ;

Instantiated with InputIterator == int, this is an exact match;
the one you propose requires a conversion of int to size_t.

This is a good example of why C++ compilers should have an option to
show what they're generating for an instantiation. Both of you are
experienced and intelligent and yet at least one of you is wrong.
Open code generation is better for a number of reasons.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net

I recommend the articles on social topics by this physics professor --
http://wuphys.wustl.edu/~katz/
 
K

Kai-Uwe Bux

mlt wrote:
mlt wrote:
I need to use a std::vector to specify a matrix of
integers (my code must not use std::boost). But is:
std::vector<std::vector<int>> vec(1,1);
vec[0][0] = 34;
an example of correct use?
No:
a) std::vector<std::vector<int>> is currently a syntax
error because of the ">>" token. Make that
std::vector< std::vector< int > >
b) The constructor arguments should read:
std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );
In general,
std::vector< std::vector< int > >
vec ( rows, std::vector< int >(cols) );
should do what you want.
Ok I see you point but currently:
std::vector<std::vector<int>> vec(1,1);
does not give any compiler error (Using Visual Studio 2008)
and when running the app I also get the correct behaviour.
So I don't think its necessary to do:
std::vector< std::vector< int > > vec ( 1, std::vector< int >(1) );
when using Visual Studio at least (have not tested on unix yet).
Well, it does not work with g++.
Presumably, whether you get an error from
std::vector<std::vector<int>> vec(1,1);
will depend on the STL that your vendor uses.

Formally, the standard requires it to work.  Whether this is
intentional or not is another question---it may be an error in
the standard.  (On the other hand: the standard has guaranteed
it, so it's rather hard to say that in fact, it is illegal, even
if the guarantee wasn't intentional.)
The constructor that gets invoked it
std::vector<T> ( size_type n, T const & t )

No.  The constructor which gets invoked is an instantiation of:

template< InputIterator >
vector::vector( InputIterator begin, InputIterator end ) ;

Instantiated with InputIterator == int, this is an exact match;
the one you propose requires a conversion of int to size_t.

This is a good example of why C++ compilers should have an option to
show what they're generating for an instantiation. Both of you are
experienced and intelligent and yet at least one of you is wrong.

The wrong one would be me. I re-checked the standard, and James is
absolutely correct. I missed that part (in fact, I missed it earlier, too;
and now I have to fix my vector implementation).
Open code generation is better for a number of reasons.

What is open code generation?


Best

Kai-Uwe Bux
 
R

red floyd

mlt said:
I need to use a std::vector to specify a matrix of integers (my code
must not use std::boost). But is:

Just to be pedantic, nobody's code may use std::boost. I don't believe
that ISO/IEC 14882:2003 defines such an entity.
 
C

coal

What is open code generation?

Code generation where the results can be reviewed by a person.
Some C++ compilers have an option that lets you inspect the
results of preprocessing. In that sense I would call them
open code generators. The same is not true with templates.
I've heard suggestions for making it easier to trace the
steps a compiler takes when it instantiates something, but I
don't know of any compilers that have that either.

Besides making it easier for people to understand what the
compiler has done, I think fully instantiated source code is
important for on line code generation. It would be the
portable output of an on line code generator rather than
attempting to generate object code for a long list of
hardware and operating systems.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net
 
J

James Kanze

(e-mail address removed) wrote: [...]
This is a good example of why C++ compilers should have an
option to show what they're generating for an instantiation.
Both of you are experienced and intelligent and yet at least
one of you is wrong.
The wrong one would be me. I re-checked the standard, and
James is absolutely correct. I missed that part (in fact, I
missed it earlier, too; and now I have to fix my vector
implementation).

It helps to have discussed the issues with someone who has
actually implemented the library. It certainly wouldn't have
occured to me on my own.

An obvious test case for the library is something like:
std::vector< int > v( 5, 10 ) ;
Without the special casing, this fails (which tends to surprise
at first). I think that in some of the initial, pre-standard
implementations of the library, it also failed; that you had to
write:
std::vector< int > v( static_cast< size_t >( 5 ), 10 ) ;
.. The committee felt that this would be too embarassing, and so
added the special case.
 

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
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top