C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why doesn't vector( size_type, const T& ) work?
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Toby Reyelts
Guest





PostPosted: Tue Dec 16, 2003 1:05 am    Post subject: Why doesn't vector( size_type, const T& ) work? Reply with quote



I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

Here's what Comeau says:

"stl_algobase.h", line 452: error: a value of type "int" cannot be
assigned
to an entity of type "A *"
*__first = __value;
^
detected during instantiation of "_OutputIter
std::fill_n(_OutputIter, _Size, const _Tp &) [with
_OutputIter=A **, _Size=int, _Tp=int]"


Since I can see the call to fill_n(), it looks like the correct
constructor is being called - vector( size_type, const T& ). Why
doesn't the compiler see 0 as an A* initialized to null rather than as
an int that is 0? I can just take up an extra line of code by
declaring a dummy A*, setting it to 0, then passing that value to the
vector constructor - but that seems quite verbose.

God bless,
-Toby Reyelts

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
John Potter
Guest





PostPosted: Tue Dec 16, 2003 10:58 am    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote



On 15 Dec 2003 20:05:11 -0500, [email]toby (AT) reyelts (DOT) com[/email] (Toby Reyelts) wrote:

Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

This is beautiful.

Quote:
Here's what Comeau says:

"stl_algobase.h", line 452: error: a value of type "int" cannot be
assigned
to an entity of type "A *"
*__first = __value;
^
detected during instantiation of "_OutputIter
std::fill_n(_OutputIter, _Size, const _Tp &) [with
_OutputIter=A **, _Size=int, _Tp=int]"

Since I can see the call to fill_n(), it looks like the correct
constructor is being called - vector( size_type, const T& ).

That is not the constructor being called because the types do not
match exactly. There is a better match for a different ctor.

Quote:
Why
doesn't the compiler see 0 as an A* initialized to null rather than as
an int that is 0?

Because at that point it is an int with value zero not the literal 0.

Quote:
I can just take up an extra line of code by
declaring a dummy A*, setting it to 0, then passing that value to the
vector constructor - but that seems quite verbose.

Just cast it in the call.

vector<A*> v( 10, static_cast<A*>(0) );

You could also fix the problem by casting the other argument.

vector<A*> v( vector<A*>::size_type(10), 0 );

Neither of the parameters wants an int, but you asked for a ctor with
two ints as arguments. There is one which matches perfectly and would
work for two iterators. That templated ctor with two of the same type
parameters matches those two ints perfectly.

Now the standard 23.1.1/9 says that your code must compile.

Quote:
template <class InputIterator
X (InputIterator f, InputIterator l, const Allocator& a = Allocator())

shall have the same effect as

X (static_cast static_cast
if InputIterator is an integral type.

Note that it states that the ctor call must have the same effect as the
other ctor call with the arguments cast to appropriate types. Both of
your compilers and g++ use internal magic to almost make it work right.
The problem is that they let the ctor be instantiated and then try to
work with the integer with value 0. If the casts are done in the call
as the required effect, there would be a static_cast of a literal 0 to
a pointer which is valid.

The standard gives one complex way to handle this which might work and
hints that there are other ways which are simpler. In this case, the
simple way missed a special case.

John

P.S. I can see Howard in pain from laughing so hard at this. Hopefully
no broken ribs. :)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
James Dennett
Guest





PostPosted: Tue Dec 16, 2003 11:01 am    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote



Toby Reyelts wrote:
Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

Here's what Comeau says:

"stl_algobase.h", line 452: error: a value of type "int" cannot be
assigned
to an entity of type "A *"
*__first = __value;
^
detected during instantiation of "_OutputIter
std::fill_n(_OutputIter, _Size, const _Tp &) [with
_OutputIter=A **, _Size=int, _Tp=int]"


Since I can see the call to fill_n(), it looks like the correct
constructor is being called - vector( size_type, const T& ).

I suspect that isn't so. Indeed, you note below that if you
*do* pass an A* then the right constructor is called and does
the right thing.

Quote:
Why
doesn't the compiler see 0 as an A* initialized to null rather than as
an int that is 0? I can just take up an extra line of code by
declaring a dummy A*, setting it to 0, then passing that value to the
vector constructor - but that seems quite verbose.

You could just write
std::vector<A*> v(10, static_cast<void*>(0));

It sounds like you've been caught by some wording in
the standard that is there to "do the right thing"
with the templated constructor that takes two values
of the same type: in your case, both ints. This wording
is there so that the ints aren't treated as iterators --
but in the case you have, you don't want them treated as
integral values either, and there the standard may well
fall short.

-- James.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
jean Davy
Guest





PostPosted: Tue Dec 16, 2003 11:17 am    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

You should type
vector<A*> v( 10 );
as by default the default value used to initialize is NULL


"Toby Reyelts" <toby (AT) reyelts (DOT) com> a écrit dans le message de
news:27f8bc71.0312151343.3559309a (AT) posting (DOT) google.com...
Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

Here's what Comeau says:

"stl_algobase.h", line 452: error: a value of type "int" cannot be
assigned
to an entity of type "A *"
*__first = __value;
^
detected during instantiation of "_OutputIter
std::fill_n(_OutputIter, _Size, const _Tp &) [with
_OutputIter=A **, _Size=int, _Tp=int]"


Since I can see the call to fill_n(), it looks like the correct
constructor is being called - vector( size_type, const T& ). Why
doesn't the compiler see 0 as an A* initialized to null rather than as
an int that is 0? I can just take up an extra line of code by
declaring a dummy A*, setting it to 0, then passing that value to the
vector constructor - but that seems quite verbose.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andreas Mueller
Guest





PostPosted: Tue Dec 16, 2003 11:25 am    Post subject: Re: Why doesn't vector( size type, const T& ) work? Reply with quote

Toby Reyelts wrote:

Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

[snip]


Hi,

looks like the compiler has problems to deduce that 0 means an A* with
the value of 0. On VC7 with its onboard STL, it will choose the wrong
ctor (vector(iterator, iterator) ). I don't know if that is legal or
not, but a simple workaround on VC7.1 is:

std::vector<A*> vA(10, static_cast<A*>(0));

It propably will work for other compilers, too.
HTH,
Andy
--
To mail me directly, remove the NO*SPAM parts in
NO*SPAMxmen40 (AT) gmx (DOT) netNO*SPAM

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gareth Stockwell
Guest





PostPosted: Tue Dec 16, 2003 11:27 am    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

Toby,

GCC 3.3.1 also disagrees with this. You're right - creating and
passing an A* solves the problem, but so does a cast:

std::vector<A*> v(10, static_cast<A*>(0));

Gareth

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Tue Dec 16, 2003 3:27 pm    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

In article <27f8bc71.0312151343.3559309a (AT) posting (DOT) google.com>, Toby
Reyelts <toby (AT) reyelts (DOT) com> writes
Quote:
Since I can see the call to fill_n(), it looks like the correct
constructor is being called - vector( size_type, const T& ). Why
doesn't the compiler see 0 as an A* initialized to null rather than as
an int that is 0? I can just take up an extra line of code by
declaring a dummy A*, setting it to 0, then passing that value to the
vector constructor - but that seems quite verbose.

Or you could write:

std::vector<A*> v(10, (A*)0);

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Dec 16, 2003 6:06 pm    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

[email]toby (AT) reyelts (DOT) com[/email] (Toby Reyelts) wrote in message
news:<27f8bc71.0312151343.3559309a (AT) posting (DOT) google.com>...
Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

Interesting case.

Quote:
Here's what Comeau says:

"stl_algobase.h", line 452: error: a value of type "int" cannot be
assigned
to an entity of type "A *"
*__first = __value;
^
detected during instantiation of "_OutputIter
std::fill_n(_OutputIter, _Size, const _Tp &) [with
_OutputIter=A **, _Size=int, _Tp=int]"


Since I can see the call to fill_n(), it looks like the correct
constructor is being called - vector( size_type, const T& ).

If the compiler and the library are conformant, the constructor being
called is the templated:

template< typename FwdIter >
vector( FwdIter begin, FwdIter end );

with FwdIter resolving to int. This is a special case, and it is
required to have the same effect as:

vector( static_cast< size_type >( begin ),
static_cast< value_type >( end ) ) ;

had been called.

The problem here is that this will take place within the constructor
itself, using the parameters of the constructor. And end (or whatever
the implementation calls it) is NOT a constant integral expression, and
thus is NOT a null pointer constant, even though it has been initialized
by the constant integral expression 0.

But that's an explination of what the implementation probably does. The
standard is quite clear -- in your case, the initialization is required
to have the same effect as:

vector::vector< A* >( static_cast< size_t >( 10 ),
static_cast< A* >( 0 ) ) ;

Which, of course, is perfectly legal, and initializes the vector with 10
null pointers. So there is a bug in both implementations. (On the
other hand, I'm not sure that what the standard requires here is even
implementable.)

Quote:
Why doesn't the compiler see 0 as an A* initialized to null rather
than as an int that is 0?

Because by the time it is deciding what to do, it is inside the
constructor, and it sees a parameter. And a parameter can never be a
constant integral expression.

Quote:
I can just take up an extra line of code by declaring a dummy A*,
setting it to 0, then passing that value to the vector constructor -
but that seems quite verbose.

Wouldn't it be easier just to say what you mean :

vector<A*> v( 10, static_cast< A* >( 0 ) ) ;

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dhruv
Guest





PostPosted: Tue Dec 16, 2003 6:22 pm    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

On Mon, 15 Dec 2003 20:05:11 -0500, Toby Reyelts wrote:

Quote:
I want to initialize a vector of pointers so that all of its elements
are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that an
int can not be converted to an A*.

This raises a new question... Is it legal to create a pointer A* that
holds the literal zero 0? Yes, of course it is. But then how come, the
implmentations fall short of recognizing this fact?

Modify line 365 of stl_vector.h for libstdc++ to read:
_M_finish = uninitialized_fill_n(_M_start, __n, _Tp(__value));

I do not know whether it is conformant for an implementation to make 2
copies of the __value parameter passed to the constructor?

Or for that matter, even this statement will fail:

v.insert (v.end (), 10, 0);


Regards,
-Dhruv.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Howard Hinnant
Guest





PostPosted: Tue Dec 16, 2003 6:25 pm    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

In article <jimstvcth5qlpmh5nhov7eaej3sndmi4bo (AT) 4ax (DOT) com>,
John Potter <jpotter (AT) falcon (DOT) lhup.edu> wrote:

Quote:
P.S. I can see Howard in pain from laughing so hard at this. Hopefully
no broken ribs. Smile

I'll be ok. <chuckle ... HAHAHAHA Ouch! Ouch! ...chuckle ... HAHAHAHA
Ouch! Ouch! ...chuckle ... HAHAHAHA Ouch! Ouch! ...> :-)

-Howard

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Tue Dec 16, 2003 9:21 pm    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

On 16 Dec 2003 13:22:44 -0500, "Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:

Quote:
Modify line 365 of stl_vector.h for libstdc++ to read:
_M_finish = uninitialized_fill_n(_M_start, __n, _Tp(__value));

I do not know whether it is conformant for an implementation to make 2
copies of the __value parameter passed to the constructor?

Placing random reinterpret_casts in standard libraries is not well
advised. _Tp(__value) is a cast expression equivalent to (_Tp)__value
and since _Tp is a pointer type and __value is type int, that is
reinterpret_cast<_Tp>(__value)

Quote:
Or for that matter, even this statement will fail:

v.insert (v.end (), 10, 0);

It fails because the implementation has a bug. Let someone who knows
what they are doing try to fix the implementation. Work around the
bug by being explicit.

v.insert(v.end(), 10, static_cast<A*>(0));

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Tue Dec 16, 2003 9:23 pm    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

In article <pan.2003.12.16.14.30.25.216948 (AT) gmx (DOT) net>, Dhruv
<dhruvbird (AT) gmx (DOT) net> writes
Quote:
This raises a new question... Is it legal to create a pointer A* that
holds the literal zero 0? Yes, of course it is. But then how come, the
implmentations fall short of recognizing this fact?

I wonder why you think that? Unless you mean that you are allowed to use
write to the pointer storage as an array of char. If address zero is not
owned by your process it is perfectly OK for the OS to close your
process down anyway it chooses so to do.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dhruv
Guest





PostPosted: Wed Dec 17, 2003 10:03 am    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

On Tue, 16 Dec 2003 16:21:21 -0500, John Potter wrote:

Quote:
On 16 Dec 2003 13:22:44 -0500, "Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:

Modify line 365 of stl_vector.h for libstdc++ to read:
_M_finish = uninitialized_fill_n(_M_start, __n, _Tp(__value));

I do not know whether it is conformant for an implementation to make 2
copies of the __value parameter passed to the constructor?

Placing random reinterpret_casts in standard libraries is not well
advised. _Tp(__value) is a cast expression equivalent to (_Tp)__value
and since _Tp is a pointer type and __value is type int, that is
reinterpret_cast<_Tp>(__value)


Ok. I thought that suppose you have:

char *A;
A = char* (0);//Amounts to reinterpret cast,
but:

struct X {
X (int);
};

X x;
x = X(0)//Valid construction? Isn't this legal?


Regards,
-Dhruv.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dhruv
Guest





PostPosted: Wed Dec 17, 2003 10:13 am    Post subject: Re: Why doesn't vector( size_type, const T& ) work? Reply with quote

On Tue, 16 Dec 2003 05:58:54 -0500, John Potter wrote:

Quote:
Note that it states that the ctor call must have the same effect as the
other ctor call with the arguments cast to appropriate types. Both of
your compilers and g++ use internal magic to almost make it work right.
The problem is that they let the ctor be instantiated and then try to
work with the integer with value 0. If the casts are done in the call
as the required effect, there would be a static_cast of a literal 0 to
a pointer which is valid.


Not quite exactly, because once the InputIterator overload has been
selected, then InputIterator gets int, and that's where the problem starts
I guess. Now, when passing down to the real ctor, type has been deduced to
be int, so static_cast<pointer_type> (integer) doesn't quite work out

Quote:
The standard gives one complex way to handle this which might work and
hints that there are other ways which are simpler. In this case, the
simple way missed a special case.

John

P.S. I can see Howard in pain from laughing so hard at this. Hopefully
no broken ribs. Smile

I guess the restricted template technique that Howard Hinnant has proposed
would work beautifully here.


Regards,
-Dhruv.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Dec 17, 2003 4:31 pm    Post subject: Re: Why doesn't vector( size type, const T& ) work? Reply with quote

"Andreas Mueller" <me (AT) privacy (DOT) net> wrote

Quote:
Toby Reyelts wrote:

I want to initialize a vector of pointers so that all of its
elements are null, so this is the code I write:

class A {
};

// Create a vector of 10 A pointers, all set to null
vector<A*> v( 10, 0 );

but both VC++ 7.1 and Comeau C++ give me a diagnostic saying that
an int can not be converted to an A*.

[snip]

looks like the compiler has problems to deduce that 0 means an A* with
the value of 0. On VC7 with its onboard STL, it will choose the wrong
ctor (vector(iterator, iterator) ).

And just which constructor should it choose? When instantiated with
iterator == int, vector(iterator,iterator) is an exact match. It's hard
to see another constructor which would be better than an exact match.

Quote:
I don't know if that is legal or not, but a simple workaround on VC7.1
is:

std::vector<A*> vA(10, static_cast<A*>(0));

It propably will work for other compilers, too.

In general, it is preferable most of the time to specify conversions
explicitly, rather than counting on implicit conversions. when dealing
with templates and/or function overloads, it is even more important.

That said, I think that we really do need a null pointer constant that
isn't an int.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.