Topic: vector<T> without T()?


Author: Bill Dimm <billd@gim.net>
Date: 1997/01/13
Raw View
Most of the member functions for vector don't seem to
require that the objects being contained have a default
constructor (only copy ctor).  So, my question is whether or not
the ANSI rules for templates and default function arguments allow
vector (etc.) to be used on a class without a default ctor
as long as no member functions requiring the default ctor
are called.  Experimentation with various compilers has
added little clarity here...

Specifically, Apr95 draft, section 14.3.2 says:
  An implementation shall not instantiate a function or a class
  that does not require instantiation... [exceptions made for
  virt funcs]
Does this imply that if a member function does not need to
be instantiated, it would be okay if the instatiation would
fail if it were attempted for that particular template argument?
(if this is not implied, why bother to make the statement above?)
One compiler I tried complained if the default ctor was used in
a member func that was never called, and two others only complained
if the member function was defined inside the class definition.

If it is okay to have a member function which uses the default ctor but
which is never instantiated, there is another potential problem.
vector has a constructor (section 23.2.5.2):
 explicit vector(size_type n, const T& value = T()
   , Allocator& = Allocator());
Does the presence of the default value T() for the second argument
prevent this constructor from being used for a type T which has
no default ctor even if the first two arguments are always supplied to
the vector constructor?  If so, why not split this constructor
into two constructors:
 explicit vector(size_type n, const T& value, Allocator& = Allocator());
 explicit vector(size_type n, Allocator& = Allocator());
where only 2nd ctor makes use of T::T()?

Thanks,
  Bill Dimm
---
[ 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: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/01/14
Raw View
Bill Dimm <billd@gim.net> writes:

>Most of the member functions for vector don't seem to
>require that the objects being contained have a default
>constructor (only copy ctor).  So, my question is whether or not
>the ANSI rules for templates and default function arguments allow
>vector (etc.) to be used on a class without a default ctor
>as long as no member functions requiring the default ctor
>are called.

Yes, that is allowed.

>Experimentation with various compilers has
>added little clarity here...
>
>Specifically, Apr95 draft, section 14.3.2 says:
>  An implementation shall not instantiate a function or a class
>  that does not require instantiation... [exceptions made for
>  virt funcs]

A lot of compilers don't (yet) comply with that rule.

>If it is okay to have a member function which uses the default ctor but
>which is never instantiated, there is another potential problem.
>vector has a constructor (section 23.2.5.2):
> explicit vector(size_type n, const T& value = T()
>   , Allocator& = Allocator());
>Does the presence of the default value T() for the second argument
>prevent this constructor from being used for a type T which has
>no default ctor even if the first two arguments are always supplied to
>the vector constructor?  If so, why not split this constructor
>into two constructors:
> explicit vector(size_type n, const T& value, Allocator& = Allocator());
> explicit vector(size_type n, Allocator& = Allocator());
>where only 2nd ctor makes use of T::T()?

Your suggestion is in fact already the status quo,
due to the following paragraph in the library introduction:

 |   17.3.4.4  Member functions                      [lib.member.functions]
 |
 | 4 Throughout    the   C++   Library   clauses   (_lib.library_   through
 |   _lib.input.output_), whenever a template member function  is  declared
 |   with one or more default arguments, this is to be understood as speci-
 |   fying a set of two or more overloaded template member functions.   The
 |   version  with  the most parameters defines the interface; the versions
 |   with fewer parameters are to be understood  as  functions  with  fewer
 |   parameters, in which the corresponding default argument is substituted
 |   in-place.  [Example: From _lib.set.cons_:
 |
 |   explicit set(const Compare &comp = Compare(),
 |                const Allocator& = Allocator());
 |
 |   This declaration is to be understood as a shorthand for the  following
 |   three declarations:
 |
 |   explicit set(const Compare& comp, const Allocator&);
 |   explicit set(const Compare& comp);
 |   explicit set();
 |
 |   In  the  second and third declarations, the default values Allocator()
 |   and Compare() are used in  place  of  the  missing  explicit  function
 |   parameters.   --end example]

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.


[ 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                             ]