 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
harkness Guest
|
Posted: Mon Dec 08, 2003 11:00 pm Post subject: question on std::vector default ctor |
|
|
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the default ctor was called only once. Which of the
following is true?
1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of
TIA (test program follows)
// vectorsize.cpp -- example of sizing a vector
#include <vector>
using std::vector;
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
// poor man's profiler I got from Dr. Cargill
#define DOTRACE
#include "Trace.h"
class MyClass
{
public:
MyClass();
friend ostream& operator<<(ostream& os, const MyClass& mc);
private:
int m_i;
};
int globali(0);
MyClass::MyClass()
{
TRACE("MyClass", "Default ctor");
cout << "assigning m_i" << endl;
m_i = globali++;
}
ostream& operator<<(ostream& os, const MyClass& mc)
{
os << mc.m_i;
return os;
}
typedef vector
typedef MVector::const_iterator MCIter;
int main()
{
srand(1); // seed
MVector mv( ; // create and initialize
// should call default ctor 8 times
int i=-1;
for(MCIter iter = mv.begin(); iter != mv.end(); ++iter)
{
cout << "mv[" << ++i << "]=" << *iter << endl;
}
return 0;
}
Output, showing only one ctor call:
..entering:MyClass Default ctor
assigning m_i
..exiting: MyClass Default ctor
mv[0]=0
mv[1]=0
mv[2]=0
mv[3]=0
mv[4]=0
mv[5]=0
mv[6]=0
mv[7]=0
--
Howard
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dag Henriksson Guest
|
Posted: Tue Dec 09, 2003 11:03 am Post subject: Re: question on std::vector default ctor |
|
|
"harkness" <harkness (AT) mail (DOT) ev1.net> skrev i meddelandet
news:200312081249.AA185925764 (AT) mail (DOT) ev1.net...
| Quote: | In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this using
gcc 3.2, and the default ctor was called only once. Which of the
following is true?
1) Josuttis was mistaken
|
Yes, I think so. The constructor used above is:
explicit vector(size_type n, const T& value = T(), const Allocator& =
Allocator());
It creates a temporary T which is used to copy initialize the 5 elements in
the vector. The default ctor should be called once and the copy ctor five
times.
--
Dag Henriksson
[ 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
|
Posted: Tue Dec 09, 2003 5:09 pm Post subject: Re: question on std::vector default ctor |
|
|
In article <v07atvoifjvuek2kqmsfa1p1vjcsaq0p3a (AT) 4ax (DOT) com>, Howard
<hlh_nospam (AT) iwon (DOT) com> writes
| Quote: | I didn't see anything in Stroustrup about this, and so far, I haven't
turned anything up with a websearch. I can't imagine that I'm the
only person to run across this. I guess it's time to break down and
order my copy of the standard.
|
What the Standard requires is that the ctor for vector<T> make n calls
to the copy ctor for T to copy the argument passed to the second
(defaulted) reference parameter of the vector ctor. The default is a
value initialised instance of T (i.e. T()).
It is common (if not universal) that the compiler generated copy ctor
for a POD is simply a call of memcpy. Try using a T with an instrumented
copy ctor and you will see what happens (though now it will no longer be
using memcpy, unless you do so within the copy ctor.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Roger Orr Guest
|
Posted: Tue Dec 09, 2003 7:59 pm Post subject: Re: question on std::vector default ctor |
|
|
"Dag Henriksson" <dag.henriksson (AT) quidsoft (DOT) se> wrote
| Quote: | "harkness" <harkness (AT) mail (DOT) ev1.net> skrev i meddelandet
news:200312081249.AA185925764 (AT) mail (DOT) ev1.net...
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
that
std::vector<T> v(5);
|
[snip]
| Quote: | The constructor used above is:
explicit vector(size_type n, const T& value = T(), const Allocator& =
Allocator());
It creates a temporary T which is used to copy initialize the 5 elements
in
the vector. The default ctor should be called once and the copy ctor five
times.
|
I would certain expect any sensible implementation would do this - but I
can't actually find anything in the standard which mandates this.
There don't seem to be any explicit complexity guarantees for this
std::vector constructor.
Roger Orr
--
MVP in C++ at www.brainbench.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Randy Maddox Guest
|
Posted: Tue Dec 09, 2003 8:08 pm Post subject: Re: question on std::vector default ctor |
|
|
"harkness" <harkness (AT) mail (DOT) ev1.net> wrote
| Quote: | In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the default ctor was called only once. Which of the
following is true?
1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of
|
Look at the ctor you are using:
explicit vector(size_type n,
const T & value = T(),
const Allocator & allocator = Allocator);
Since you are passing only the size_type n argument the others
default. So the default ctor for T is called once and the copy ctor
for T is called 5 times.
Randy.
[ 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
|
Posted: Tue Dec 09, 2003 8:09 pm Post subject: Re: question on std::vector default ctor |
|
|
"harkness" <harkness (AT) mail (DOT) ev1.net> wrote
| Quote: | In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this
using gcc 3.2, and the default ctor was called only once. Which of the
following is true?
1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of
|
If this is actually what Josuttis wrote, he is mistaken. (He actually
wrote the book some time ago, when the library was still in a state of
flux, but I don't think that this point has changed.) Your statement is
the equivalent of:
std::vector< T > v( 5, T() ) ;
In this statement, the standard requires the default constructor to be
called once, and the copy constructor to be called 5 times.
--
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 |
|
 |
John Potter Guest
|
Posted: Tue Dec 09, 2003 8:10 pm Post subject: Re: question on std::vector default ctor |
|
|
On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:
| Quote: | In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the
default ctor was called only once. Which of the following is true?
1) Josuttis was mistaken
|
The above uses the ctor with a defaulted T(). There is no vector ctor
that takes only a size_type.
std::vector<T> v(5, T());
Now table 67 states that the sequence is constructed from n copies of
the supplied t. Instrument your copy ctor to see the copies.
Disclaimer: This could be written as two ctors with one taking a
size_type and the other taking a size_type and a T. I can't find
anything which allows or forbids using n default constructions in the
case of the size_type only ctor. However, there is nothing which
requires n default constructions.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Dec 09, 2003 10:06 pm Post subject: Re: question on std::vector default ctor |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] writes:
| Quote: | "harkness" <harkness (AT) mail (DOT) ev1.net> wrote in message
news:<200312081249.AA185925764 (AT) mail (DOT) ev1.net>...
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this
using gcc 3.2, and the default ctor was called only once. Which of the
following is true?
1) Josuttis was mistaken
2) The standard has changed
3) This is a gcc 3.2 bug (optimization?)
4) It's due to some other reason I haven't thought of
If this is actually what Josuttis wrote, he is mistaken. (He actually
wrote the book some time ago, when the library was still in a state of
flux, but I don't think that this point has changed.) Your statement is
the equivalent of:
std::vector< T > v( 5, T() ) ;
|
That form is permitted, but it is not a requirement.
| Quote: | In this statement, the standard requires the default constructor to be
called once, and the copy constructor to be called 5 times.
|
This is wrong. The Standard does not require the default constructor
to be called once and the copy constructor to be called 5 times.
Rather, the Standard permits both behaviour.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Dec 09, 2003 10:11 pm Post subject: Re: question on std::vector default ctor |
|
|
John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:
| Quote: | On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:
In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
std::vector<T> v(5);
calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the
default ctor was called only once. Which of the following is true?
1) Josuttis was mistaken
The above uses the ctor with a defaulted T(). There is no vector ctor
that takes only a size_type.
std::vector<T> v(5, T());
Now table 67 states that the sequence is constructed from n copies of
the supplied t. Instrument your copy ctor to see the copies.
Disclaimer: This could be written as two ctors with one taking a
size_type and the other taking a size_type and a T. I can't find
anything which allows or forbids using n default constructions in the
case of the size_type only ctor. However, there is nothing which
requires n default constructions.
|
The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ 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
|
Posted: Wed Dec 10, 2003 11:17 am Post subject: Re: question on std::vector default ctor |
|
|
On 9 Dec 2003 17:11:50 -0500, Gabriel Dos Reis
<gdr (AT) integrable-solutions (DOT) net> wrote:
| Quote: | John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:
| Disclaimer: This could be written as two ctors with one taking a
| size_type and the other taking a size_type and a T. I can't find
| anything which allows or forbids using n default constructions in the
| case of the size_type only ctor. However, there is nothing which
| requires n default constructions.
The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.
|
I thought I said that. If it does, it could either default construct
one item and copy construct N from it or default construct N. Or can
it? It must use the allocator. How do you default construct using an
allocator? The member and uninitialized_X algorithms all copy
construct. Is it allowed to use placement new in allocated space?
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bjarne Stroustrup Guest
|
Posted: Wed Dec 10, 2003 11:25 am Post subject: Re: question on std::vector default ctor |
|
|
Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote
| Quote: | In article <v07atvoifjvuek2kqmsfa1p1vjcsaq0p3a (AT) 4ax (DOT) com>, Howard
[email]hlh_nospam (AT) iwon (DOT) com[/email]> writes
I didn't see anything in Stroustrup about this, and so far, I haven't
turned anything up with a websearch. I can't imagine that I'm the
only person to run across this. I guess it's time to break down and
order my copy of the standard.
What the Standard requires is that the ctor for vector<T> make n calls
to the copy ctor for T to copy the argument passed to the second
(defaulted) reference parameter of the vector ctor. The default is a
value initialised instance of T (i.e. T()).
It is common (if not universal) that the compiler generated copy ctor
for a POD is simply a call of memcpy. Try using a T with an instrumented
copy ctor and you will see what happens (though now it will no longer be
using memcpy, unless you do so within the copy ctor.
|
That's correct, but I'd like my 2 cents about the "I didn't see
anything in Stroustrup about this".
On pg 447 there is a coment "n copies of val" and a paragraph that
elements are initialized by the default constructor of the element
type that I suspect could easily be misread. Luckily, pg 944 I happen
to use exactly the initialize-with-n-copies-of-val constructor for
vector as an illustration of exception safety techniques, so you can
see what is done and how.
- Bjarne Stroustrup; http://www.research.att.com/~bs
[ 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
|
Posted: Wed Dec 10, 2003 11:38 am Post subject: Re: question on std::vector default ctor |
|
|
Gabriel Dos Reis wrote:
| Quote: | kanze (AT) gabi-soft (DOT) fr writes:
| "harkness" <harkness (AT) mail (DOT) ev1.net> wrote in message
| news:<200312081249.AA185925764 (AT) mail (DOT) ev1.net>...
|
| > In _The C++ Standard Library_ by Josuttis, page 149, is the assertion
| > that
|
| > std::vector<T> v(5);
|
| > calls the default ctor of T 5 times. I wrote a test case for this
| > using gcc 3.2, and the default ctor was called only once. Which of the
| > following is true?
|
| > 1) Josuttis was mistaken
| > 2) The standard has changed
| > 3) This is a gcc 3.2 bug (optimization?)
| > 4) It's due to some other reason I haven't thought of
|
| If this is actually what Josuttis wrote, he is mistaken. (He actually
| wrote the book some time ago, when the library was still in a state of
| flux, but I don't think that this point has changed.) Your statement is
| the equivalent of:
|
| std::vector< T > v( 5, T() ) ;
That form is permitted, but it is not a requirement.
|
How so? There is no single-argument constructor taking
an integral value directly specified: while the library
may be allowed to add one, its behaviour must surely still
be as if the version with a default argument were used --
and that version cannot rely on being able to use the
default constructor, as it must work with types which have
no default constructor.
All I see is that
| Quote: | | In this statement, the standard requires the default constructor to be
| called once, and the copy constructor to be called 5 times.
This is wrong. The Standard does not require the default constructor
to be called once and the copy constructor to be called 5 times.
Rather, the Standard permits both behaviour.
|
How so? Where is the freedom to do this (which is beyond
the "as if" rule) granted?
I do accept that you may well know of rules that I don't
recall, or might not have been aware of -- if so, I would
like to fill one more gap in my knowledge.
I think James Kanze's expectation is that there is an
equivalence by definition between the form
std::vector<T> v(5);
and
std::vector<T> v(5, T());
and I find that expectation a reasonable one based on my
reading of the standard.
-- James.
[ 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
|
Posted: Wed Dec 10, 2003 11:39 am Post subject: Re: question on std::vector default ctor |
|
|
Gabriel Dos Reis wrote:
| Quote: | John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:
| On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:
|
| > In _The C++ Standard Library_ by Josuttis, page 149, is the assertion that
|
| > std::vector<T> v(5);
|
| > calls the default ctor of T 5 times. I wrote a test case for this using gcc 3.2, and the
| > default ctor was called only once. Which of the following is true?
|
| > 1) Josuttis was mistaken
|
| The above uses the ctor with a defaulted T(). There is no vector ctor
| that takes only a size_type.
|
| std::vector<T> v(5, T());
|
| Now table 67 states that the sequence is constructed from n copies of
| the supplied t. Instrument your copy ctor to see the copies.
|
| Disclaimer: This could be written as two ctors with one taking a
| size_type and the other taking a size_type and a T. I can't find
| anything which allows or forbids using n default constructions in the
| case of the size_type only ctor. However, there is nothing which
| requires n default constructions.
The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.
So long as the effects of calling those separate functions are |
the same (up to the usual "as if" games) as would be achieved
were a single member with default arguments used and called,
no?
Granted, a user can often tell the difference with regular
member functions (e.g. by trying to take the address of one,
cast to a suitable type to detect its presence) but I would
expect that the effect of calling a substituted function
should be the same as calling the version explicitly defined
by the standard.
-- James.
[ 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
|
Posted: Wed Dec 10, 2003 3:59 pm Post subject: Re: question on std::vector default ctor |
|
|
Gabriel Dos Reis <gdr (AT) integrable-solutions (DOT) net> wrote
| Quote: | John Potter <jpotter (AT) falcon (DOT) lhup.edu> writes:
| On 8 Dec 2003 18:00:33 -0500, "harkness" <harkness (AT) mail (DOT) ev1.net> wrote:
| > In _The C++ Standard Library_ by Josuttis, page 149, is the
| > assertion that std::vector<T> v(5);
| > calls the default ctor of T 5 times. I wrote a test case for this
| > using gcc 3.2, and the default ctor was called only once. Which
| > of the following is true?
| > 1) Josuttis was mistaken
| The above uses the ctor with a defaulted T(). There is no vector
| ctor that takes only a size_type.
| std::vector<T> v(5, T());
| Now table 67 states that the sequence is constructed from n copies
| of the supplied t. Instrument your copy ctor to see the copies.
| Disclaimer: This could be written as two ctors with one taking a
| size_type and the other taking a size_type and a T. I can't find
| anything which allows or forbids using n default constructions in
| the case of the size_type only ctor. However, there is nothing
| which requires n default constructions.
The Standard says that whenever a member function is described to take
default arguments, the implementation is permitted to "split" that
member function into as many parts.
|
True, but it doesn't authorize different semantics for the two
variants. If an implementation splits the two, it must still ensure
that the std::vector<T>::vector( size_t ) constructor meets the
requirements given in table 67 for X(n, t), in particular, that it
"constructs a sequence with n copies of t".
The wording could definitly be more precise, but since calling the copy
constructor could have observable behavior, and there is no special
wording to allow eliding it here, so I would interpret this requirement
to mean that the copy constructor must be called at least n times. I'm
far from sure that this is the intent, but it is definitly a reasonable
interpretation of what the standard actually says.
--
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 |
|
 |
Daniel Krügler (nee Spang Guest
|
Posted: Wed Dec 10, 2003 4:14 pm Post subject: Re: question on std::vector default ctor |
|
|
Hello, John Potter!
John Potter schrieb:
| Quote: | I thought I said that. If it does, it could either default construct
one item and copy construct N from it or default construct N. Or can
it? It must use the allocator. How do you default construct using an
allocator? The member and uninitialized_X algorithms all copy
construct. Is it allowed to use placement new in allocated space?
|
Actually some days ago I stumbled about the same restriction of
std::allocator.
To my opinion its interface should be extended to allow placement new
default construction (construct(T*) overload). The reason is: Also the
Standard Libary Container Classes does require CopyConstructible
as an property of its contents, this might have different performance and
exception guarantees.
Could we demand, that construct(T*) does either not exist or its call
should not be a well-defined expression, in case of classes, which don't
provide the DefaultConstructible requirement? (SFINAE might help here)
Greetings from Bremen,
Daniel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|