Topic: STL Problem
Author: "John I. Moore, Jr." <jimoore@erols.com>
Date: 1996/11/09 Raw View
John E. Potter wrote:
>
> I have read several technical replies and learned a few things. I
> would like to inject a practical view. IMHO, the Standard Library
> containers, iterators, and algorithms are a framework which was
> carefully designed to include the container built in array and
> the iterator builtin pointer. The builtin array requires a default
> constructor which is a precedent for the others. The map must have
> a default initial value for operator[] to make an insertion. This
> value could be supplied rather than the type having a default
> constructor; however, this still requires a value which does not
> make any sence.
This is incorrect. The "builtin array" does not require a default
constructor if it is explicitly initialized. For example, if X is a
class with only one constructor of the form X(int) (i.e., no default
constructor), then we could create an array of X objects by declaring
X a[] = { X(1), X(2), X(3), X(4), X(5) };
Admittedly this is clumsy if you need to initialize a large array, but
the lack of a default constructor doesn't actually prevent the use of
arrays.
The comment about a map requiring a default constructor for insertion
may actually be true (I haven't looked at the issue in detail), but
I'm not sure why the list would need one. I implemented a list which
didn't require a default constructor.
> At one time I held the posted view that some classes should not have
> default constructors; however, I have found this view too restrictive
> and now assure them for all classes. An unrelated restriction is
> declaring a variable and reading a value. A class without a default
> constructor is just not generally usable.
I disagree. It is too general a statement to say that all classes need
a default constructor. Quoting from a better known authority, Carroll and
Ellis, in their book on Designing and Coding Reusable C++, state that
"Attempts to define a minimal standard interface for all classes, although
well motivated, are misguided. No function should be provided by every
class." They give examples to illustrate.
--
John I. Moore, Jr. phone: (301) 924-0680
SoftMoore Consulting email: 70672.1744@compuserve.com
16233 Monty Court
Rockville, MD 20853-1344
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jpotter@falcon.lhup.edu (John E. Potter)
Date: 1996/11/13 Raw View
John I. Moore, Jr. (jimoore@erols.com) wrote:
: John E. Potter wrote:
: >
: > I have read several technical replies and learned a few things. I
: > would like to inject a practical view. IMHO, the Standard Library
: > containers, iterators, and algorithms are a framework which was
: > carefully designed to include the container built in array and
: > the iterator builtin pointer. The builtin array requires a default
: > constructor which is a precedent for the others. The map must have
: > a default initial value for operator[] to make an insertion. This
: > value could be supplied rather than the type having a default
: > constructor; however, this still requires a value which does not
: > make any sence.
: This is incorrect. The "builtin array" does not require a default
: constructor if it is explicitly initialized. For example, if X is a
: class with only one constructor of the form X(int) (i.e., no default
: constructor), then we could create an array of X objects by declaring
: X a[] = { X(1), X(2), X(3), X(4), X(5) };
: Admittedly this is clumsy if you need to initialize a large array, but
: the lack of a default constructor doesn't actually prevent the use of
: arrays.
Yes, I think we are in agreement. The lack of a default constructor
does not make use of arrays impossible, just impractical. I also
think that my arguement that array is a precedent is rather weak. In
the cases where an array is impractical, a vector is likely a better
choice anyway.
: The comment about a map requiring a default constructor for insertion
: may actually be true (I haven't looked at the issue in detail), but
: I'm not sure why the list would need one. I implemented a list which
: didn't require a default constructor.
A map<Key, T> does not require either default constructor; however, it
does require a default value for T. As an associative array,
operator[] always finds a key (ie. adds it) and must have a value
to associate with it. The default value can be supplied to the map
constructor; so, map does not require T to have a default constructor.
But, then there can be no default constructor for map. Is that
reasonable?
For vector and deque, the requirement for a default constructor could
be removed. The constructor which sets an initial size would require
an initial element value. I do not see any other problems.
For list and set, as you said, there is no need.
: > At one time I held the posted view that some classes should not have
: > default constructors; however, I have found this view too restrictive
: > and now assure them for all classes. An unrelated restriction is
: > declaring a variable and reading a value. A class without a default
: > constructor is just not generally usable.
: I disagree. It is too general a statement to say that all classes need
: a default constructor. Quoting from a better known authority, Carroll and
: Ellis, in their book on Designing and Coding Reusable C++, state that
: "Attempts to define a minimal standard interface for all classes, although
: well motivated, are misguided. No function should be provided by every
: class." They give examples to illustrate.
Agreed. All absolutes are wrong, including this one;-) What I should have
said was that at one time, I considered the lack of a reasonable default
value sufficient reason for not having a default constructor. After
becoming my own client and finding that too restrictive, my current
view is that if a collection (including persistence) of objects is
reasonable, it is also reasonable to have a default constructor.
Workarounds are possible, but that just postpones the problem.
With that view, it does not bother me at all that the containers
require default constructors. Just my pragmatic opinion. Thank you
for correcting my overstatements.
John
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Julian Pardoe <pardoej@lonnds.ml.com>
Date: 1996/11/01 Raw View
David Vandevoorde wrote:
>
> >>>>> "TG" == Timo Geusch <Timo_Geusch@award.de> writes:
> TG> IMHO, this is due to the design of the STL containers. The
> TG> containers must be able to create an empty object when enlarging
> TG> the container.
>
> No, you can provide a value for `fill-in'. All that is needed is
> an accessible copy-constructor, an accessible destructor, an
> accessible operator& that returns the same pointer as the built-in
> version, and a copy-assignment operation (operator=) which returns
> the target object by reference.
Couldn't the container get extra space in the form of 'raw storage'
and use placement new and the copy constructor to copy a value into
it? Something like:
void ValueContainer::Insert (const T &that)
{
void *p = Allocate (); // allocate some raw storage using
// private method
new (p) T (that); // convert to a copy of 'that'
}
(This was an issue for us when using RogueWave because the default
constructor for RWTime sets the object to the current time, making
some simple container operations ridiculously expensive. (Having
the default constructor set an RWTime object to the current time is
an outrageously poor piece of design but that's another story.))
-- jP --
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1996/11/01 Raw View
Julian Pardoe <pardoej@lonnds.ml.com> writes:
> Couldn't the container get extra space in the form of 'raw storage'
> and use placement new and the copy constructor to copy a value into
> it? Something like:
It could, yes. As far as I know, all STL implementations do actually
use this technique. The free HP implementation does, and so does the
SGI implementation. (SGI's implementation isn't yet publicly
available, but we will be putting it on a public WWW site some time in
the middle of this month.)
In fact, a conforming STL implementation almost has to use this
technique, or some technique that is equivalent to it. The member
function vector<T>::reserve(n) (see subclause 23.2.4.2
[lib.vector.capacity] of the September '96 WP) allocates at least
enough memory for n objects of type T, but does not construct new
objects. That is, vector<T>::size() returns the number of objects in
the vector and vector<T>::capacity() returns the number of objects
that the vector has allocated storage for; capacity() can be (and
usually is) larger than size().
Types stored in containers are required to have copy constructors,
assignment operators, and destructors, but they are not required to
have default constructors. The requirements are spelled out
explicitly in subclause 23.1 [lib.container.requirements] of the
working paper.
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jpotter@falcon.lhup.edu (John E. Potter)
Date: 1996/11/04 Raw View
John.I.Moore@mhadf.production.compuserve.com, () wrote:
: I have a question about the design of the Standard Template
: Library. I have a number of classes without default
: constructors. They have constructors, but there isn't a
: meaningful set of default values, and I prefer that the user
: initialize them explicitly. The objects are small in size, and I
: would like to store the actual objects (not pointers) in an STL
: container class. The problem is that my implementation (Borland
: C++ with the Rogue Wave STL implementation) will not permit
: instantiation of an STL container class if the class doesn't have
: a default constructor. I haven't tried all of the container
: classes, but it fails on several of them.
: My question is: is this restriction a result of the design of
: STL, or is it simply a result of the Rogue Wave implementation?
I have read several technical replies and learned a few things. I
would like to inject a practical view. IMHO, the Standard Library
containers, iterators, and algorithms are a framework which was
carefully designed to include the container built in array and
the iterator builtin pointer. The builtin array requires a default
constructor which is a precedent for the others. The map must have
a default initial value for operator[] to make an insertion. This
value could be supplied rather than the type having a default
constructor; however, this still requires a value which does not
make any sence.
At one time I held the posted view that some classes should not have
default constructors; however, I have found this view too restrictive
and now assure them for all classes. An unrelated restriction is
declaring a variable and reading a value. A class without a default
constructor is just not generally usable.
John
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "John.I.Moore@mhadf.production.compuserve.com,
Date: 1996/10/28 Raw View
I have a question about the design of the Standard Template
Library. I have a number of classes without default
constructors. They have constructors, but there isn't a
meaningful set of default values, and I prefer that the user
initialize them explicitly. The objects are small in size, and I
would like to store the actual objects (not pointers) in an STL
container class. The problem is that my implementation (Borland
C++ with the Rogue Wave STL implementation) will not permit
instantiation of an STL container class if the class doesn't have
a default constructor. I haven't tried all of the container
classes, but it fails on several of them.
My question is: is this restriction a result of the design of
STL, or is it simply a result of the Rogue Wave implementation?
I seem to recall a similar problem in trying to use the HP
version of STL. I have written my own container classes in the
past, and the only requirement that I placed on the template
parameter classes was that they have a copy constructor. In
general, this should be sufficient for implementation of a
container class, and it is the minimum that the container
class implementor should need for implementation.
John I. Moore, Jr. phone: (301) 924-0680
SoftMoore Consulting email: 70672.1744@compuserve.com
16233 Monty Court
--
John I. Moore, Jr. phone: (301) 924-0680
SoftMoore Consulting email: 70672.1744@compuserve.com
Providing object-oriented training and consulting services.
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 1996/10/31 Raw View
Hi,
John.I.Moore@mhadf.production.compuserve.com wrote:
: I have a question about the design of the Standard Template
: Library. I have a number of classes without default
: constructors. They have constructors, but there isn't a
: meaningful set of default values, and I prefer that the user
: initialize them explicitly. The objects are small in size, and I
: would like to store the actual objects (not pointers) in an STL
: container class. The problem is that my implementation (Borland
: C++ with the Rogue Wave STL implementation) will not permit
: instantiation of an STL container class if the class doesn't have
: a default constructor. I haven't tried all of the container
: classes, but it fails on several of them.
: My question is: is this restriction a result of the design of
: STL, or is it simply a result of the Rogue Wave implementation?
It is not a restriction of STL and probably also not of the Rogue Wave
implementation (well, depends how you view it...). It is more likely to
be a restriction of the compiler: According to the standard, code of
templates which is never used for a certain instantiation is not
created and the instantiation does not depend on additional
requirements resulting from this omitted code. However, this rule is
not yet widely implemented. Here is an example of the problem: One of
the constructors of 'vector<T>' takes a size of the array and an
optional initial value. The declaration looks something like this:
template <class T, .../* additional, here irrelevant, arguments */>
class vector
{
public:
vector(size_type size, T const &init = T());
//... other stuff
};
These default arguments are about the only places, where the containers
want a default constructor: In all other places default constructors
are deliberatly avoided. Now, according to the standard, if the
'vector' for a specific type is never used (including the construction
mentioned above) in a way using the default argument, there is no need
for the default constructor and thus the compiler should not check
whether a default constructor is present and never refer to it.
Unfortunately, several current compilers reject a use of the container
classes, even if it does not depend on default arguments...
Whether the problems you have are to be considered a compiler or a
library problem, depends on the way how you see the decision of Rogue
Wave to put the default arguments in: If they avoided them, every use
of a member with a default argument like the one above would need the
argument to be specified (e.g. by explicitly calling the default
constructor for an object). Apart from being surprising for users new
to STL (as the text books on STL rely on the default argument to be
present), this would only be a [minor] inconvenience. The advantage
would be, that "non-nice classes" (see e.g. "Designing and Coding
Reusable C++", Caroll & Ellis, Addison-Wesley, for a definition of
"nice classes") could use the containers in spite of the compiler
limitations. Apparently, Rogue Wave decided this is a compiler, not a
library, issue and that not all users should be forced to specify the
argument. The result is, that only "nice classes" can be put into these
containers with this compiler. In any case, it is not an STL problem:
With a standard conforming compiler, there should be no problem...
(well, the problem currently remaining is to get a standard conforming
compiler, especially without a standard).
: I seem to recall a similar problem in trying to use the HP
: version of STL. I have written my own container classes in the
: past, and the only requirement that I placed on the template
: parameter classes was that they have a copy constructor. In
: general, this should be sufficient for implementation of a
: container class, and it is the minimum that the container
: class implementor should need for implementation.
I guess, you also required a destructor...: It is not necessary to have
publically accessible destructor. One use of a private destructor is
to disallow creation of objects on the stack (this could be useful
e.g. for reference counted objects). In any case, without a public
destructor you would be unable to release the objects stored in the
container.
--
<mailto:dietmar.kuehl@uni-konstanz.de>
<http://www.informatik.uni-konstanz.de/~kuehl/>
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/10/31 Raw View
>>>>> "TG" == Timo Geusch <Timo_Geusch@award.de> writes:
TG> John.I.Moore@mhadf.production.compuserve.com,"Jr."
[...]
>> My question is: is this restriction a result of the design
>> of STL, or is it simply a result of the Rogue Wave implementation?
I don't think it is inherent to the STL (or rather draft standard
library's) specs.
TG> IMHO, this is due to the design of the STL containers. The
TG> containers must be able to create an empty object when enlarging
TG> the container.
No, you can provide a value for `fill-in'. All that is needed is
an accessible copy-constructor, an accessible destructor, an
accessible operator& that returns the same pointer as the built-in
version, and a copy-assignment operation (operator=) which returns
the target object by reference.
TG> From my experience, all classes used with STL
TG> containers should have the following member functions:
TG> - Default constructor
TG> - Copy constructor
TG> - Assignment operator
TG> - less-than operator (if the sequence must be sorted)
TG> - operator==
I think you can provide a comparison functor in most or all cases.
Daveed
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Timo Geusch" <Timo_Geusch@award.de>
Date: 1996/10/31 Raw View
John.I.Moore@mhadf.production.compuserve.com,"Jr."
<70672.1744@CompuServe.COM> wrote in article
<552qfc$k26$1@mhadf.production.compuserve.com>...
> I have a question about the design of the Standard Template
> Library. I have a number of classes without default
> constructors. They have constructors, but there isn't a
> meaningful set of default values, and I prefer that the user
> initialize them explicitly. The objects are small in size, and I
> would like to store the actual objects (not pointers) in an STL
> container class. The problem is that my implementation (Borland
> C++ with the Rogue Wave STL implementation) will not permit
> instantiation of an STL container class if the class doesn't have
> a default constructor. I haven't tried all of the container
> classes, but it fails on several of them.
> My question is: is this restriction a result of the design of
> STL, or is it simply a result of the Rogue Wave implementation?
IMHO, this is due to the design of the STL containers. The containers must
be able to create an empty object when enlarging the container. From my
experience, all classes used with STL containers should have the following
member functions:
- Default constructor
- Copy constructor
- Assignment operator
- less-than operator (if the sequence must be sorted)
- operator==
--
Timo Geusch
PCMCIA software engineer
AWARD Software International, Inc.
"Opinions stated in this message are solely my own and do not refelct the
official view of AWARD Software International, Inc in any way"
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]