Topic: Help: need templates that don't require types w/ default constructors.


Author: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/04/29
Raw View
Steve DSa wrote:
> Dear Colleagues,
> I read Scott Meyers book, "More Effective C++" (c 1996).
> In it he says on page 19, "Avoid gratuitous default constructors".
>
> In some cases it makes sense to avoid default constructors
> because we don't want to initialize objects without insisting on
> important information needed to construct the object.

One counter-argument is that (some people believe that) constructors
should be as lightweight as possible.  In particular, they shouldn't
do anything that would throw an exception.  One way to ensure this
is to code them so that they do little more than initialize their
object to an "empty" state, and then supply other member functions
that embue the object with the "important information".  These other
member functions can then do more dangerous operations (such as
allocate memory, generate I/O, dereference pointers, etc.) that
could throw exceptions.

I should also point out that regardless of whether or not you use
default constructors, and whether or not they are lightweight or
heavyweight, it is absolutely essential that they initialize EVERY
member of their object (especially pointer members).  Uninitialized
data is sinful, and there is no excuse for it when using a language
with so many capabilities.

--
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Steve D'Sa" <sdsa@incyte.com>
Date: 1998/04/29
Raw View
This is a multi-part message in MIME format.
--------------D07FC11DB3B5A0C98D16BFDA
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

This is interesting, I've never tried to write an allocator. Perhaps an
allocator that uses placement new would work. (If it somehow causes  the
compiler to avoid checking the template functions that require the type's
default constructors.) I'll try and get back to you on that.

Meanwhile, I've seeded this discussion in other news groups as well
(comp.lang.c++, comp.lang.c++.moderated, comp.lang.c++.leda).

Originally I thought this was a problem with the SGI template library I was
using.  The general consensus is that it is a problem with the complier.

The problem is that there are member functions within the template that DO
require the type's default constructor. When you try to create a template class
the compiler checks for consistency and correctness for these functions as well,
even though they will not be called upon within your program. Consistency and
correctness should only be checked for the functions in the template that the
programmer is using, this, I believe, is or should be standard practice.

The ideal solution is to use a different compiler (Borland's apparently works
fine, but not microsoft's visual C++ 5.0) OR if stuck with the bad compiler, the
programmer can provide a 'bogus' default constructor that will throw an
exception if called. You can then catch this exception in the main program ( I
tried this and it works).

But, your suggestion about allocators might be key. Maybe, my visual c++
compiler isn't bad, but my allocator is.
I'm afraid I don't know much about allocators.

Cheers,
sd




Terence Kelling wrote:

> Are you sure that you can't find template vectors that don't require default
> constructors?  I think that the internal mechanism they use according to the
> standard is by using the 'allocator' class which allows allocation of just
> raw memory and then uses a sort of placement new operator to put the actual
> objects at specified locations.
>
> If this isn't clear enough, a psuedo-code representation would be something
> like this:
>
> template <class type> allocator {
>
>    private:
>       char* base;
>       size_t offset;
>
>    public:
>       allocator(void);
>       ~allocator(void);
>
>       place_obj(const type& obj);
> };
>
> // allocate a contiguous block of uninitialized memory
> template <class type>
> allocator<type>::allocator(void) : base(0), offset(0) {
>
>    base = malloc(sizeof(type) * number_of_elements_in_array);
> }
>
> // clean up
> template <class type>
> allocator<type>::~allocator(void) {
>
>    free(base);
> }
>
> // place an object in array using the class' copy constructor
> template <class type>
> void allocator<type>::place_class(const type& obj) {
>    new(base+offset) type(obj);
>    offset+= sizeof(type);
> }
>
> Hope this was helpful.
>
> Terence Kelling
>
> Steve DSa wrote:
>
> > Dear Colleagues,
> > I read Scott Meyers book, "More Effective C++" (c 1996).
> > In it he says on page 19, "Avoid gratuitous default constructors".
> >
> > In some cases it makes sense to avoid default constructors
> > because we don't want to initialize objects without insisting on
> > important information needed to construct the object.
> >
> > The example Scott gives:
> > An object modelling an entry into an address book would not
> > make sense if it wasn't initialized with an address parameter.
> > What good is an Address book with empty entries?
> >
> > However,
> > not having a default constructor puts a programmer in a bad situation,
> > He/She can't make use of  TEMPLATES which REQUIRE
> > user-defined datatypes to have  DEFAULT CONSTRUCTORS.
> >
> > Scott assures us that this is only a result of bad template design, and
> > goes on to
> > show examples of  it, but so far,  I haven't found a template library
> > that implements vectors or hashes maps so they
> > don't require default constructors.
> >
> > I was hoping LEDA would be exceptional.
> > Is LEDA addressing this issue?
> > HELP!
> ---
> [ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]



--------------D07FC11DB3B5A0C98D16BFDA
Content-Type: text/x-vcard; charset=us-ascii; name="vcard.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Steve D'Sa
Content-Disposition: attachment; filename="vcard.vcf"

begin:          vcard
fn:             Steve D'Sa
n:              D'Sa;Steve
org:            Incyte Pharmaceuticals
adr:            3145 Porter Drive;;;Palo Alto;CA;94304;United States
email;internet: sdsa@incyte.com
title:          Scientific Programmer
tel;work:       (650) 845 5768
note:           Perl, C, C++ are my areas of expertise, along with molecular biology.
x-mozilla-cpt:  ;0
x-mozilla-html: TRUE
version:        2.1
end:            vcard


--------------D07FC11DB3B5A0C98D16BFDA--
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/01
Raw View
Terence Kelling wrote:
>
> Are you sure that you can't find template vectors that don't require default
> constructors? ...

Section 20.1.4 says:
| The default constructor is not required.  Certain container class mem-
| ber  function  signatures specify the default constructor as a default
| argument.  T() must be a well-defined expression (_dcl.init_)  if  one
| of   those   signatures   is   called   using   the  default  argument

Thus, you can always avoid the need for a default constructor, by
providing an explicit value whenever using one of those functions.
Example (assume MyClass has no default constructor):

#include <vector>
MyClass filler = /* Expression involving non-default construction */;

// Not permitted -- attempts to fill vec1 with MyClass():
std::vector<MyClass> vec1(10);
std::vector<MyClass> vec(10, filler); // Legal

vec.resize(15);    // Illegal
vec.resize(15, filler);   // Legal
vec.insert(vec.begin());  // Illegal
vec.insert(vec.begin(), filler); // Legal

...
> Steve DSa wrote:
...
> > not having a default constructor puts a programmer in a bad situation,
> > He/She can't make use of  TEMPLATES which REQUIRE
> > user-defined datatypes to have  DEFAULT CONSTRUCTORS.
> >
> > Scott assures us that this is only a result of bad template design, and
> > goes on to
> > show examples of  it, but so far,  I haven't found a template library
> > that implements vectors or hashes maps so they
> > don't require default constructors.

Then those vector<> implementations don't conform to the proposed
standard. The standard specifies that library template functions
described with default arguments should actually be implemented as
seperate functions, one with and one without the optional argument. That
allows the version with the optional argument to be instantiated even if
the default value for that argument would involve code that could not be
instantiated with those template arguments. Perhaps those implementors
overlooked that requirement.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Steve DSa <sdsa@incyte.com>
Date: 1998/04/25
Raw View
Dear Colleagues,
I read Scott Meyers book, "More Effective C++" (c 1996).
In it he says on page 19, "Avoid gratuitous default constructors".

In some cases it makes sense to avoid default constructors
because we don't want to initialize objects without insisting on
important information needed to construct the object.

The example Scott gives:
An object modelling an entry into an address book would not
make sense if it wasn't initialized with an address parameter.
What good is an Address book with empty entries?

However,
not having a default constructor puts a programmer in a bad situation,
He/She can't make use of  TEMPLATES which REQUIRE
user-defined datatypes to have  DEFAULT CONSTRUCTORS.

Scott assures us that this is only a result of bad template design, and
goes on to
show examples of  it, but so far,  I haven't found a template library
that implements vectors or hashes maps so they
don't require default constructors.

I was hoping LEDA would be exceptional.
Is LEDA addressing this issue?
HELP!
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Terence Kelling <kelling@arlut.utexas.edu>
Date: 1998/04/27
Raw View
Are you sure that you can't find template vectors that don't require default
constructors?  I think that the internal mechanism they use according to the
standard is by using the 'allocator' class which allows allocation of just
raw memory and then uses a sort of placement new operator to put the actual
objects at specified locations.

If this isn't clear enough, a psuedo-code representation would be something
like this:

template <class type> allocator {

   private:
      char* base;
      size_t offset;

   public:
      allocator(void);
      ~allocator(void);

      place_obj(const type& obj);
};

// allocate a contiguous block of uninitialized memory
template <class type>
allocator<type>::allocator(void) : base(0), offset(0) {

   base = malloc(sizeof(type) * number_of_elements_in_array);
}

// clean up
template <class type>
allocator<type>::~allocator(void) {

   free(base);
}


// place an object in array using the class' copy constructor
template <class type>
void allocator<type>::place_class(const type& obj) {
   new(base+offset) type(obj);
   offset+= sizeof(type);
}

Hope this was helpful.

Terence Kelling

Steve DSa wrote:

> Dear Colleagues,
> I read Scott Meyers book, "More Effective C++" (c 1996).
> In it he says on page 19, "Avoid gratuitous default constructors".
>
> In some cases it makes sense to avoid default constructors
> because we don't want to initialize objects without insisting on
> important information needed to construct the object.
>
> The example Scott gives:
> An object modelling an entry into an address book would not
> make sense if it wasn't initialized with an address parameter.
> What good is an Address book with empty entries?
>
> However,
> not having a default constructor puts a programmer in a bad situation,
> He/She can't make use of  TEMPLATES which REQUIRE
> user-defined datatypes to have  DEFAULT CONSTRUCTORS.
>
> Scott assures us that this is only a result of bad template design, and
> goes on to
> show examples of  it, but so far,  I haven't found a template library
> that implements vectors or hashes maps so they
> don't require default constructors.
>
> I was hoping LEDA would be exceptional.
> Is LEDA addressing this issue?
> HELP!
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]