Topic: constructor calls in vectors
Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Thu, 23 May 2002 08:50:13 GMT Raw View
John Nagle <nagle@animats.com> writes:
|> James Kanze wrote:
|> > I would argue that this is the correct interpretation. I'm not
|> > 100% sure, however, since I don't think that there is any
|> > requirement concerning the default constructor, and there is a
|> > guarantee that it is NOT called in constructing the vector. (It
|> > may be called to construct the argument to the constructor, of
|> > course.)
|> I once reported that as a bug in some STL implementation. New
|> objects were created by invoking the default constructor, then
|> assigning, rather than by invoking the copy constructor. It was a
|> bug; only by accident did it work that way.
That is definitly non-conforming.
|> This typically comes up when an class contains a data member
|> which is a reference. That reference has to be initialized during
|> construction, and so the default constructor is usually not
|> meaningful. Thus, there's a reason to get this right.
I was thinking more of the case where instead of using a default
argument, the implementor provides two constructors:
vector<T>::vector( size_t )
vector<T>::vector( size_t, T const& )
The second *MUST* use only the copy constructor; no call to the
default constructor is allowed, as it must work with classes without
default constructors.
The formal semantics of the first are to default construct a T, then
copy it. My question is rather whether using only the default
constructor is a legal optimization.
--=20
James Kanze mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: James Kanze <kanze@alex.gabi-soft.de>
Date: Tue, 21 May 2002 16:41:23 GMT Raw View
Gabriel Dos Reis <gdr@codesourcery.com> writes:
|> James Dennett <jdennett@acm.org> writes:
|> | Francis Glassborow wrote:
|> | > In article <ac1iu6$222i$1@agate.berkeley.edu>, Eric J. Korpela=20
|> | > <korpela@ellie.ssl.berkeley.edu> writes
|> | >> Quick (or maybe not so quick) std::vector question. Does the
|> | >> standard specify what constructors will be called during
|> | >> creation of a vector? For example when I have classes like
|> | >> the following...
|> | >> class A {
|> | >> public:
|> | >> int i;
|> | >> A(); // Constructor: Details left to the im=
agination
|> | >> A(const A &a); // Copy Constuctor: Ditto
|> | >> };
|> | >> int main(void) {
|> | >> std::vector<A> B(1024));
|> | >> }
|> | >> My problem is in porting some code between two platforms. On
|> | >> one platform the A() constructor is called for every element.
|> | > see 23.2.4.1. where the signature of the relevant ctor for
|> | > vector strongly implies that the copy ctor is expected to be
|> | > used to initialise the elements of a vector. I do not see
|> | > anything that forbids the alternative.
|> | The fact that the behaviour is specified; there's a single construc=
tor
|> ^^^^^^
|> | which takes a size_type argument and a defaulted const reference to
|> | ElementType (followed by a defaulted allocator argument which I'm
|> | largely ignoring here),
|> Actually, the standard is a little more permissive than that:
|> 17.4.4.4/2:
|> An implementation can declare additional non-virtual member functio=
n
|> signatures within a class: =20
|> --- by adding arguments with default values to a member function
|> signature;172) The same latitude does not extend to the
|> implementation of virtual or global functions, however. =20
|> --- by replacing a member function signature with default values b=
y
|> two or more member function signatures with *equivalent behavi=
or*;
|> --- by adding a member function signature for a member function na=
me.=20
|> (Emphasis is mine)
|> | and it is specified as filling the vector with copies of the
|> | second argument by Table 67 (from sequence container
|> | requirements).
|> Agreed, by a literal reading of the standard.
Except that your point is well taken; the standard requires that the
copy constructor for objects in a standard container have strictly
copy semantics (as we well know from the discussions about
std::auto_ptr). Since apparantly, this was not the case of the
original poster, his code is actually undefined behavior, and both
compilers/libraries were right.
I would argue that this is the correct interpretation. I'm not 100%
sure, however, since I don't think that there is any requirement
concerning the default constructor, and there is a guarantee that it
is NOT called in constructing the vector. (It may be called to
construct the argument to the constructor, of course.)
--=20
James Kanze mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)179 2607481
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Wed, 22 May 2002 20:16:48 GMT Raw View
James Kanze wrote:
> I would argue that this is the correct interpretation. I'm not 100%
> sure, however, since I don't think that there is any requirement
> concerning the default constructor, and there is a guarantee that it
> is NOT called in constructing the vector. (It may be called to
> construct the argument to the constructor, of course.)
I once reported that as a bug in some STL implementation.
New objects were created by invoking the default constructor,
then assigning, rather than by invoking the copy constructor.
It was a bug; only by accident did it work that way.
This typically comes up when an class contains a data
member which is a reference. That reference has to be
initialized during construction, and so the default
constructor is usually not meaningful. Thus, there's
a reason to get this right.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: korpela@ellie.ssl.berkeley.edu (Eric J. Korpela)
Date: Fri, 17 May 2002 17:43:16 GMT Raw View
Quick (or maybe not so quick) std::vector question. Does the
standard specify what constructors will be called during creation
of a vector? For example when I have classes like the following...
class A {
public:
int i;
A(); // Constructor: Details left to the imagination
A(const A &a); // Copy Constuctor: Ditto
};
int main(void) {
std::vector<A> B(1024));
}
My problem is in porting some code between two platforms. On one platform
the A() constructor is called for every element. On the other, the A()
constructor is called once and the copy constructor is used to transfer
its value to the other elements of the vector. For most initializations
this wouldn't be a problem. However, in this case the vector is an
initial state vector for a Monte Carlo simulation. The A() constructor
is used to build the initial state. As the copy constructor is used
elsewhere, I can't easily change its definition to mimic the constructor.
At any rate, the questions are... Is either of these compilers doing
something in violation of the standard? Any suggestions on how to change
the code to work on both? The A() constructor is used fairly frequently.
As is the copy constructor. Add a new vector constructor?
Any assistance appreciated.
Eric
--
Eric Korpela | An object at rest can never be
korpela@ssl.berkeley.edu | stopped.
<a href="http://setiathome.ssl.berkeley.edu/~korpela">Click for home page.</a>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Fri, 17 May 2002 18:29:21 GMT Raw View
Eric J. Korpela wrote:
> Quick (or maybe not so quick) std::vector question. Does the
> standard specify what constructors will be called during creation
> of a vector? For example when I have classes like the following...
>
> class A {
> public:
> int i;
> A(); // Constructor: Details left to the imagination
> A(const A &a); // Copy Constuctor: Ditto
> };
>
> int main(void) {
> std::vector<A> B(1024));
> }
>
> My problem is in porting some code between two platforms. On one platform
> the A() constructor is called for every element. On the other, the A()
> constructor is called once and the copy constructor is used to transfer
> its value to the other elements of the vector.
The standard behaviour is to use the copy constructor to initialize
the elements of the vector. Any library that uses the default
constructor repeatedly is non-conforming.
--
James Dennett <jdennett@acm.org>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 17 May 2002 19:42:25 GMT Raw View
In article <ac1iu6$222i$1@agate.berkeley.edu>, Eric J. Korpela
<korpela@ellie.ssl.berkeley.edu> writes
>Quick (or maybe not so quick) std::vector question. Does the
>standard specify what constructors will be called during creation
>of a vector? For example when I have classes like the following...
>
>class A {
> public:
> int i;
> A(); // Constructor: Details left to the imagination
> A(const A &a); // Copy Constuctor: Ditto
>};
>
>int main(void) {
> std::vector<A> B(1024));
>}
>
>My problem is in porting some code between two platforms. On one platform
>the A() constructor is called for every element.
see 23.2.4.1. where the signature of the relevant ctor for vector
strongly implies that the copy ctor is expected to be used to initialise
the elements of a vector. I do not see anything that forbids the
alternative.
>On the other, the A()
>constructor is called once and the copy constructor is used to transfer
>its value to the other elements of the vector. For most initializations
>this wouldn't be a problem. However, in this case the vector is an
>initial state vector for a Monte Carlo simulation. The A() constructor
>is used to build the initial state. As the copy constructor is used
>elsewhere, I can't easily change its definition to mimic the constructor.
Really? Won't that cause problems elsewhere when the compiler elects to
make a copy or is it always OK to create an entirely new object even
when a copy is asked for.
>
>At any rate, the questions are... Is either of these compilers doing
>something in violation of the standard? Any suggestions on how to change
>the code to work on both? The A() constructor is used fairly frequently.
>As is the copy constructor. Add a new vector constructor?
I am not sure how you would manage to do that, even if you were willing
to risk the consequences of changing Standard Library code.
>
>Any assistance appreciated.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 17 May 2002 20:12:20 GMT Raw View
In article <3CE543B6.1040209@acm.org>, James Dennett <jdennett@acm.org>
writes
>The standard behaviour is to use the copy constructor to initialize
>the elements of the vector. Any library that uses the default
>constructor repeatedly is non-conforming.
While I know that is the normal behaviour, where does the standard
require it?
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Fri, 17 May 2002 20:12:27 GMT Raw View
Francis Glassborow wrote:
> In article <ac1iu6$222i$1@agate.berkeley.edu>, Eric J. Korpela
> <korpela@ellie.ssl.berkeley.edu> writes
>
>> Quick (or maybe not so quick) std::vector question. Does the
>> standard specify what constructors will be called during creation
>> of a vector? For example when I have classes like the following...
>>
>> class A {
>> public:
>> int i;
>> A(); // Constructor: Details left to the imagination
>> A(const A &a); // Copy Constuctor: Ditto
>> };
>>
>> int main(void) {
>> std::vector<A> B(1024));
>> }
>>
>> My problem is in porting some code between two platforms. On one
>> platform
>> the A() constructor is called for every element.
>
>
> see 23.2.4.1. where the signature of the relevant ctor for vector
> strongly implies that the copy ctor is expected to be used to initialise
> the elements of a vector. I do not see anything that forbids the
> alternative.
The fact that the behaviour is specified; there's a single constructor
which takes a size_type argument and a defaulted const reference to
ElementType (followed by a defaulted allocator argument which I'm
largely ignoring here), and it is specified as filling the vector
with copies of the second argument by Table 67 (from sequence
container requirements).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Fri, 17 May 2002 20:22:55 GMT Raw View
Francis Glassborow wrote:
> In article <3CE543B6.1040209@acm.org>, James Dennett <jdennett@acm.org>
> writes
>
>> The standard behaviour is to use the copy constructor to initialize
>> the elements of the vector. Any library that uses the default
>> constructor repeatedly is non-conforming.
>
>
> While I know that is the normal behaviour, where does the standard
> require it?
The first line of Table 67 (in 23.1.1) says that for a sequence
container,
ContainerType a(n, t);
constructs a sequence with n copies of t.
23.2.4.1 says that there is a vector constructor
explicit vector(size_type n,
const T& value = T(),
const Allocator& = Allocator());
Therefore
std::vector<T> a(n);
is equivalent to
std::vector<T> a(n, T());
which by the quote from table 67 above means that the elements
of the container are created with the copy constructor (indirectly
through the allocator for some reason, possibly).
--
James Dennett <jdennett@acm.org>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Gabriel Dos Reis <gdr@codesourcery.com>
Date: Sat, 18 May 2002 19:34:53 GMT Raw View
James Dennett <jdennett@acm.org> writes:
| Francis Glassborow wrote:
| > In article <ac1iu6$222i$1@agate.berkeley.edu>, Eric J. Korpela
| > <korpela@ellie.ssl.berkeley.edu> writes
| >
| >> Quick (or maybe not so quick) std::vector question. Does the
| >> standard specify what constructors will be called during creation
| >> of a vector? For example when I have classes like the following...
| >>
| >> class A {
| >> public:
| >> int i;
| >> A(); // Constructor: Details left to the imagination
| >> A(const A &a); // Copy Constuctor: Ditto
| >> };
| >>
| >> int main(void) {
| >> std::vector<A> B(1024));
| >> }
| >>
| >> My problem is in porting some code between two platforms. On one
| >> platform
| >> the A() constructor is called for every element.
| >
| >
| > see 23.2.4.1. where the signature of the relevant ctor for vector
| > strongly implies that the copy ctor is expected to be used to initialise
| > the elements of a vector. I do not see anything that forbids the
| > alternative.
|
| The fact that the behaviour is specified; there's a single constructor
^^^^^^
| which takes a size_type argument and a defaulted const reference to
| ElementType (followed by a defaulted allocator argument which I'm
| largely ignoring here),
Actually, the standard is a little more permissive than that:
17.4.4.4/2:
An implementation can declare additional non-virtual member function
signatures within a class:
--- by adding arguments with default values to a member function
signature;172) The same latitude does not extend to the
implementation of virtual or global functions, however.
--- by replacing a member function signature with default values by
two or more member function signatures with *equivalent behavior*;
--- by adding a member function signature for a member function name.
(Emphasis is mine)
| and it is specified as filling the vector
| with copies of the second argument by Table 67 (from sequence
| container requirements).
Agreed, by a literal reading of the standard.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]