[Effective-cpp] Item 35: Familiarize yourself with the language standard

Terje Slettebø tslettebo at chello.no
Tue Jun 10 08:59:07 EDT 2003


>From: "Jaspreet Singh" <Jasingh at quark.co.in>

>  the ADT programming style is a bit different from the OO
> style i think the "class T" is just a workaround for a parent "Object"
class as in
> java

Just to add to what Adrian said. I think calling "class T" as a workaround
for a base class is to get it backwards. Rather, it's because Java doesn't
have generics (templates) (at least until recently), it has to do it instead
with a base class, virtual functions, and ugly casts that may fail at
run-time (rather than being statically checked). Java has recently got
generics, too, which means you may get type-checked containers there, as
well.

Generic programming is relatively new (ok, Ada had it in 1983, so we're
talking "relatively", here), compared to e.g. OO, so it may not be that
widely understood.

As both Scott Meyers, and Adrian, said, templates are essential in much
modern code. As it said in the item, almost all of the standard library is
templated.

To give you a hint of the power of generic programming and concepts:
Consider the algorithm that was presented earlier in this thread:

template<class T>
T * find( T * begin, T *end, cont T& value )
{
  while (begin != end && *begin != value) ++begin;

  return begin;
}

Because it doesn't assume the type of T, it can be used with any type that
"models the concept", i.e. that conforms to the concept requirement. In this
case, T is required to be a model of the concept InputIterator. Whatever
type conforms to this, can be used. That means that it must provide a "!=",
"*", and "++" operator, etc.

The really clever thing in STL is that the concepts are defined in such a
way that you may use both fundamental types and user-defined types. The
above algorithm may be used with UDTs having those operators overloaded, so
it works as an iterator, and it also works for regular pointers.

This is something you don't get by requiring all to inherit from a common
base class.

Other advantages of templates over a base class:

- Efficiency - With templates, the binding is done at compile-time, so
there's no virtual function calls, and code may be inlined. This means that
the code can be just as efficient as hand-written code. Also, the objects
are stored _by value_, so you avoid the overhead of dynamical allocation and
garbage collection or reference counting.

- Static type checking - With templates, you get the type checking at
compile-time, whereas with a base class, everything has to be expressed in
terms of the base class, e.g. Object, and cast to/from this, when
inserted/retrieved to/from containers. This adds overhead of run-time type
checking, and means you risk getting a run-time exception. For example,
there's nothing stopping you from putting Apples into a container of
Oranges, but you'd get an exception if you tried to retrieve it.

> a template can be used whenever we need a family of classes/functions...
but
> i haven't come across such a situation.

That's probably because you haven't taken advantage of generic programming,
and instead used a base class and, virtual functions, even when templates
may be used instead.


Regards,

Terje




More information about the Effective-cpp mailing list