By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,230 Members | 2,471 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,230 IT Pros & Developers. It's quick & easy.

These template things are good...right?

P: n/a
Perhaps I'm just a bit frustrated, and I will soon realize the clear truth
of the matter, but right now I have some serious misgivings about the value
of investing a lot of time and effort into template programming. I just
finished reading the first 12 chapters of _C++ Templates: The Complete
Guide_. One thing that struck me as I read these chapters is how much I
didn't know about C++. I _know_ the core language specification is
contained in a finite document, but I sometimes get the sense that C++
requires an infinite amount of learning.

The primary C++ language (without templates) is substantial and quite
powerful in itself. There are many aspects of that which I have yet to
fully master. While I will grant that working with templates can help
shore up some of those skills, I have to wonder how useful templates really
are. I have discovered that code using templates can frequently not behave
as I expect or want. An example is the std::for_each algorithm. I use the
for-each idiom frequently in other languages, and also use the Cpp
implementation provided with Qt (though that has significant limitations in
its own right). The std::for_each, however, has proved virtually useless
to me.

Will a programmer who knows how to use templates very well be significantly
more productive than one who sticks to the traditional OOP aspects of C++?
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 7 '06 #1
Share this Question
Share on Google+
35 Replies


P: n/a

Steven T. Hatton wrote:
Will a programmer who knows how to use templates very well be significantly
more productive than one who sticks to the traditional OOP aspects of C++?
Yes.

Dec 7 '06 #2

P: n/a
Steven T. Hatton wrote:
[.. gripe, gripe ..]
Will a programmer who knows how to use templates very well be
significantly more productive than one who sticks to the traditional
OOP aspects of C++?
In what team, doing what? IOW, yes, if using templates is what is
required from that programmer. No, if using templates is not in
his/her everyday activity.

However, consider what you yourself wrote: while reading the book on
templates you have discovered how much you didn't know of the "core"
C++ language. It is conceivable that the "one who sticks to the
traditional OOP aspects of C++" is actually not as knowledgeable
where the "core" C++ is concerned than one thinks one is.

Can you learn to read a human language and claim proficiency in it
without, say, being able to talk? There were people who were very
versed in a foreign language without knowing how the words they read
or write are pronounced. Are they missing much? I don't know. How
do you actually measure that? What I can say is that their knowledge
is incomplete and very artificial. They are definitely missing some
jokes based on how words are pronounced... Of course, if they stick
to the traditional scientific language, they can even be productive
in an environment where they don't need to talk or understand speech
or understand jokes based on word play.

Does that answer your concerns?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Dec 7 '06 #3

P: n/a

Steven T. Hatton wrote:
Will a programmer who knows how to use templates very well be significantly
more productive than one who sticks to the traditional OOP aspects of C++?
For more advanced use of templates, it is much simpler if the compiler
you are using is reasonably standard conformant, else it can be
frustrating. For instance the Template book you cite would be little
use in practise with VC++6.0 or gcc < 3.0 methinks.

Maybe that's obvious to many, but OTOH it may not be so if you are in
the position of only ever having used an older compiler.

regards
Andy Little

Dec 7 '06 #4

P: n/a
Steven T. Hatton wrote:
Perhaps I'm just a bit frustrated, and I will soon realize the clear truth
of the matter, but right now I have some serious misgivings about the value
of investing a lot of time and effort into template programming. I just
finished reading the first 12 chapters of _C++ Templates: The Complete
Guide_. One thing that struck me as I read these chapters is how much I
didn't know about C++. I _know_ the core language specification is
contained in a finite document, but I sometimes get the sense that C++
requires an infinite amount of learning.
It's not infinite but it is a monster learning curve. Probably less of
a monster today than 6-5 years agro because there is so many more good
examples and the compilers only in the last 2-3 years have finally
started to behave well enough that the intention of the standards
writers are being met.
>
The primary C++ language (without templates) is substantial and quite
powerful in itself. There are many aspects of that which I have yet to
fully master. While I will grant that working with templates can help
shore up some of those skills, I have to wonder how useful templates really
are. I have discovered that code using templates can frequently not behave
as I expect or want. An example is the std::for_each algorithm. I use the
for-each idiom frequently in other languages, and also use the Cpp
implementation provided with Qt (though that has significant limitations in
its own right). The std::for_each, however, has proved virtually useless
to me.
Why is std::foreach "virtually useless" to you ?

Templates are a very important part of C++. They allow you to maintain
the strong type safety of the language yet provide a typeless interface.
Templates are less than optimal, in the sense that the language was
not originally designed with templates in mind, however having said that
the problems are only superficial (issues like needing to use the
typename and template keyword in some strange places).

As an example, I recently had a legacy file type I needed to create a
parser for, the specification is a disaster (look at the dxf specs). I
basically took the spec, wrapped a few templates around them and I was
able to capture the specification almost as written. This is alot
easier to maintain than having to create tables by hand from the spec.
Will a programmer who knows how to use templates very well be significantly
more productive than one who sticks to the traditional OOP aspects of C++?
Yes.

I'll give you an example.

We needed to create an "installer" that without a doubt required to be
tweaked ad infinitum. We discussed this and one engineer wanted to use
"expressions" using templates and another simply wanted to hard code it.
The "hard coding" guy started the development but the "expressions"
guys decided to prototype installer expressions anyway. Installer
expressions became part of the product and we ended up using it in
multiple ways that quite frankly were never part of the original thought
but worked amazingly well. Had we kept on with the hard coded methods,
we would probably have been fixing bugs in it for a while to come.

In this example it was syntactic sugar but it made two things happen:
a) it was much easier to maintain because it made making stupid errors
much harder to make.
b) forced an object model onto you that also reduced the number of errors.

Even though the templates themselves were a little complex, the
maintainer of the actual "expressions" didn't need to know the complexity.

Most of the other engineers that were aware were skeptical of using this
methodology at the time so if you do push the envelope, expect there to
be less knowledgeable and less enthusiastic developers around you being
openly skeptical.

As for templates in general, they are very very useful. Arguably, they
are the most important part of the language.

Dec 7 '06 #5

P: n/a
Victor Bazarov wrote:
Steven T. Hatton wrote:
>[.. gripe, gripe ..]
Will a programmer who knows how to use templates very well be
significantly more productive than one who sticks to the traditional
OOP aspects of C++?

In what team, doing what? IOW, yes, if using templates is what is
required from that programmer. No, if using templates is not in
his/her everyday activity.

However, consider what you yourself wrote: while reading the book on
templates you have discovered how much you didn't know of the "core"
C++ language. It is conceivable that the "one who sticks to the
traditional OOP aspects of C++" is actually not as knowledgeable
where the "core" C++ is concerned than one thinks one is.

Can you learn to read a human language and claim proficiency in it
without, say, being able to talk? There were people who were very
versed in a foreign language without knowing how the words they read
or write are pronounced. Are they missing much? I don't know. How
do you actually measure that? What I can say is that their knowledge
is incomplete and very artificial. They are definitely missing some
jokes based on how words are pronounced... Of course, if they stick
to the traditional scientific language, they can even be productive
in an environment where they don't need to talk or understand speech
or understand jokes based on word play.

Does that answer your concerns?

V
Not really. But that's probably because my concerns are such that there
really is no answer than "there's only one way to find out". I guess I'm
feeling discouraged by the number of idiosyncracies I have learned lurk
under the guise of templates. The way I see things right now, template
programming is kind of like programming the compiler to write code rather
than simply using the compiler to compile the code we write. It requires a
fairly good understanding of the compilation stages in order to do anything
beyond the basics. The knowledge and understanding will likely be useful
regardless of whether templates themselves prove useful to me.

I do have to ask myself, however, what do I get out of creating templates
which adapt to the type I instantiate them with in order to create
functions or classes? How much /reuse/ am I really likely to get out of a
template? One exercise I undertook several months ago was to create my own
vector math library using templates. You helped me work out some of the
trickier parts, you may recall. So now I have a vector math library which
is some ways is better than any others I have seen. I can instantiate the
templates with float or double. For what I'm doing, I almost always use
float because its faster, leaner, and sufficiently precise.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 7 '06 #6

P: n/a

Steven T. Hatton skrev:
Perhaps I'm just a bit frustrated, and I will soon realize the clear truth
of the matter, but right now I have some serious misgivings about the value
of investing a lot of time and effort into template programming.
[snip]
Do not invest more time than you believe pays then.
>
The primary C++ language (without templates) is substantial and quite
powerful in itself. There are many aspects of that which I have yet to
fully master. While I will grant that working with templates can help
shore up some of those skills, I have to wonder how useful templates really
are. I have discovered that code using templates can frequently not behave
as I expect or want. An example is the std::for_each algorithm. I use the
for-each idiom frequently in other languages, and also use the Cpp
implementation provided with Qt (though that has significant limitations in
its own right). The std::for_each, however, has proved virtually useless
to me.
std::for_each does not require an understanding of templates.
>
Will a programmer who knows how to use templates very well be significantly
more productive than one who sticks to the traditional OOP aspects of C++?
You do not need to be an expert, but a reasonable understanding would
be a definite advantage. I do use templates but do not believe I am an
expert. Still theres a lot of benefit from using templates as it
reduces lots of repetitive tasks.

/Peter

Dec 7 '06 #7

P: n/a

peter koch wrote:
std::for_each does not require an understanding of templates.
True, however since it is a template then understanding how templates
bitch when you do something dumb is a pretty important ability to have
in using it.

In my opinion you can't really call yourself a C++ programmer if you
can't use the STL. Not understanding templates limits your ability to
use the standard library significantly.

Dec 7 '06 #8

P: n/a
Steven T. Hatton napsal(a):
The std::for_each, however, has proved virtually useless to me.

Will a programmer who knows how to use templates very well be significantly
more productive than one who sticks to the traditional OOP aspects of C++?
I do not know the book, but it will certainly cover creating your own
templated classes and procedures. I would suggest start with what others
created first. It's easy and might give you beter idea of what templates
are all about.

Look at Standard Template Library. Try containers first. They are
probably as good as you would write them "from scratch", unless you have
some special cases of use. They are error free - at least compared to
what you will probably create in first few versions of your code. They
are type-safe - for both primitives and classes - with or without common
base class. And they are instant and ready to use.

Have a look at SGI implementation - the documentation contains example
snipets of code which might be more illustrative than some "deep" book.

Along the way you will certainly discover why std::for_each() and other
templated algorithms are usefull.

For me the STL alone is enough of "good-thing" that templates bring to
C++. So far I have used templates in my own designs just few times -
mainly for my own data-structures and their manipulation.

Ales

BTW: The lates big improvement of Java which is mature OOP language, was
introduction of templates (although not so powerful) as the C++ once.
Dec 7 '06 #9

P: n/a
peter koch wrote:
>
Steven T. Hatton skrev:
>>The std::for_each, however, has proved virtually useless
to me.
std::for_each does not require an understanding of templates.
How else would it be implemented? This is what is specified in the
Standard:

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);

Now, suppose I have a collection of nodes in a scene graph, each node is a
composite of arbitrary complexity. I want to iterate over the nodes and
apply a rotation to each of them. std::for_each will not do it. I can
make std::transform work, but the amount of code needed to do so is much
more than is needed to write

for(unsigned i=0; i < coll.size();++i) coll[i]->rotate(m);

IIRC, I can't use a local class with std::transform because I can't pass it
to a function template. There /is/ this proposal:

http://www.open-std.org/JTC1/SC22/WG...005/n1796.html

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 7 '06 #10

P: n/a

Steven T. Hatton skrev:
peter koch wrote:

Steven T. Hatton skrev:
>The std::for_each, however, has proved virtually useless
to me.
std::for_each does not require an understanding of templates.

How else would it be implemented? This is what is specified in the
Standard:
Well.... if you demand to know how every library function you use is
implemented, there's a lot of nontemplated code you'd have to not call.
It is correct that you need to know what to pass to the function, but
that hardly requires you to be a template expert.

/Peter

Dec 8 '06 #11

P: n/a
On Thu, 07 Dec 2006 19:18:24 -0500, Steven T. Hatton wrote:
peter koch wrote:
>>
Steven T. Hatton skrev:
>>>The std::for_each, however, has proved virtually useless
to me.
std::for_each does not require an understanding of templates.

How else would it be implemented? This is what is specified in the
Standard:

template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);

Now, suppose I have a collection of nodes in a scene graph, each node is a
composite of arbitrary complexity. I want to iterate over the nodes and
apply a rotation to each of them. std::for_each will not do it.
Why not?
I can make std::transform work, but the amount of code needed to do so is
much more than is needed to write

for(unsigned i=0; i < coll.size();++i) coll[i]->rotate(m);
Maybe in some particular case, yes. There may be other cases where using
for_each is clearer and/or more efficient.
/.../
--
Lionel B
Dec 8 '06 #12

P: n/a

Noah Roberts skrev:
peter koch wrote:
std::for_each does not require an understanding of templates.

True, however since it is a template then understanding how templates
bitch when you do something dumb is a pretty important ability to have
in using it.

In my opinion you can't really call yourself a C++ programmer if you
can't use the STL. Not understanding templates limits your ability to
use the standard library significantly.
There is a difference between "understanding" and "having an
understanding of". To use the standard C++ library simply requires you
to "have an understanding of".
Being able to write simple templated classes and functions should be a
requirement of every C++ programmer, but there is still a way to go if
you want to write the big, advanced template-libraries such as e.g. the
boost spirit library or some of Alexandrescus genious and insightful
typemanipulating libraries.

/Peter

Dec 8 '06 #13

P: n/a
peter koch wrote:
>
Steven T. Hatton skrev:
>peter koch wrote:
>
Steven T. Hatton skrev:
The std::for_each, however, has proved virtually useless
to me.
std::for_each does not require an understanding of templates.

How else would it be implemented? This is what is specified in the
Standard:
Well.... if you demand to know how every library function you use is
implemented, there's a lot of nontemplated code you'd have to not call.
It is correct that you need to know what to pass to the function, but
that hardly requires you to be a template expert.

/Peter
After looking at things more closely, I now realize I /could/ use
std::for_each with a visitor pattern.

One of the problems with std::for_each in this context is that the way the
Standard read at the time Josuttis wrote TC++SL only specified means of
invoking constant member functions on collection elements using the member
function adapters.

"Note that member functions called by mem_fun_ref and mem_fun must
be /constant/ member functions. Unfortunately, the C++ standard library
does not provide function adapters form nonconstant member functions (I
discovered this while writing this book). ..."

I do not know if that has changed.

My point was not that I need to be a template expert to use the STL. It was
that the STL has some limitations which make me wonder if the approach is
really ideal. In some ways the STL approach is antithetical to object
oriented programming. I know what Stroustrup had to say about Hegel
but....

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 8 '06 #14

P: n/a

Steven T. Hatton skrev:
peter koch wrote:
[snip]
My point was not that I need to be a template expert to use the STL. It was
that the STL has some limitations which make me wonder if the approach is
really ideal. In some ways the STL approach is antithetical to object
oriented programming. I know what Stroustrup had to say about Hegel
but....
STL has nothing to do with object-oriented programming. Actually, I do
believe that e.g. Java would have problems creating a clean
"ForEach"-interface. Also the fact that there is a for_each function
does not mandate that you should use it. Use it if you find that it
makes your code more readable, and use a loop if thats more convenient
to you. Personally, I would prefer the loop if I had to e.g. create a
new class and theres nothing wrong with that approach.

/Peter

Dec 8 '06 #15

P: n/a
peter koch wrote:
Steven T. Hatton skrev:
peter koch wrote:
[snip]
My point was not that I need to be a template expert to use the STL. It was
that the STL has some limitations which make me wonder if the approach is
really ideal. In some ways the STL approach is antithetical to object
oriented programming. I know what Stroustrup had to say about Hegel
but....

STL has nothing to do with object-oriented programming. Actually, I do
believe that e.g. Java would have problems creating a clean
"ForEach"-interface.
Java has something that's arguibly better, which is a foreach loop.
http://java.sun.com/j2se/1.5.0/docs/...e/foreach.html

I say it's better because to use std::for_each you have to pass a
functor that does what you want in the third parameter, which means
that if you don't have one ready you either have to go off and write a
function first, or use boost::lambda (which can't always give you what
you want). No such requirement for Java's, because it's just a loop. At
the same time, if you DO have a function handy, Java's syntax is
essentially no more weildy than std::for_each.

(Java stole this from C#, which probably stole it from somewhere else.)

I'm not sure how it works behind the scenes though; it may be less
flexible in some sense than std::for_each because you can use that with
any class that gives you the proper iterators. foreach probably
requires a subclass of Collection or something.

Evan

(BTW, overall I like programming in C++ more than Java -- I feel
constrained in the latter, like "I *should* be able to do this, C++
would let me do this" -- but there are some spiffy things in Java, and
it's new for loop construct is one of them. It's syntactic sugar
(though the link makes the argument that it's syntactic sugar that
helps you avoid errors), but hey, I like sweets.)

Dec 8 '06 #16

P: n/a

Evan wrote:
peter koch wrote:
Steven T. Hatton skrev:
peter koch wrote:
[snip]
My point was not that I need to be a template expert to use the STL. It was
that the STL has some limitations which make me wonder if the approach is
really ideal. In some ways the STL approach is antithetical to object
oriented programming. I know what Stroustrup had to say about Hegel
but....
STL has nothing to do with object-oriented programming. Actually, I do
believe that e.g. Java would have problems creating a clean
"ForEach"-interface.

Java has something that's arguibly better, which is a foreach loop.
http://java.sun.com/j2se/1.5.0/docs/...e/foreach.html

I say it's better because to use std::for_each you have to pass a
functor that does what you want in the third parameter, which means
that if you don't have one ready you either have to go off and write a
function first, or use boost::lambda (which can't always give you what
you want). No such requirement for Java's, because it's just a loop. At
the same time, if you DO have a function handy, Java's syntax is
essentially no more weildy than std::for_each.
It's really a completely different construct. Two strengths of C++'s
version are:

1) can be called on any range of data not just a complete collection
2) can be called on a variety of constructs that are not collections,
has a more general interface.

As you said, there is boost::lambda but there is also boost::bind or
tr1::bind that will perform better in many situations.

If you want something more closely resembling a foreach loop found in
Java, Perl, etc... then have a look at BOOST_FOREACH

http://www.boost.org/regression-logs...l/foreach.html

Dec 8 '06 #17

P: n/a
peter koch wrote:
>
Steven T. Hatton skrev:
>peter koch wrote:
[snip]
>My point was not that I need to be a template expert to use the STL. It
was that the STL has some limitations which make me wonder if the
approach is
really ideal. In some ways the STL approach is antithetical to object
oriented programming. I know what Stroustrup had to say about Hegel
but....

STL has nothing to do with object-oriented programming.
I don't fully agree with that. There are class templates used to implement
collections and function objects, etc. The use of classes is certainly an
aspect of OOP. Where the STL diverges from OOP is in having functionality
separated into collections, iterators and algorithms, rather than
consolidating the data and functionality into a single class construct.
With OOP and inheritance, an interface is formally stated in the code.
With generic programming, the interface is a "pure abstraction". That's
where "concepts" come in.
Actually, I do
believe that e.g. Java would have problems creating a clean
"ForEach"-interface.
Actually, the for-each construct is part of the core Java language. It is
implemented as a syntactic alternative to the traditional for-loop.

void rotateAll(Collection<Nodec, Matrix m) {for(Node n :c) n.rotate(m);}
Also the fact that there is a for_each function
does not mandate that you should use it. Use it if you find that it
makes your code more readable, and use a loop if thats more convenient
to you. Personally, I would prefer the loop if I had to e.g. create a
new class and theres nothing wrong with that approach.
Nothing wrong with creating a new class to perform an operation which can
easily be done in one line of code, and not even eliminating the original
line of code? There are times when it makes sense to use a visitor pattern
with function objects, but there are also many times when it serves no
other purpose than the complicate the code.

The situation in which I wanted to operate on a collection of nodes is
something I actually encountered, and after reviewing things, I now realize
that I /did/ implement it using a std::for_each and an inner class. It
was "the C++" way to do it. Then I realized that it was also the hard way
to do it, and reverted to using a traditional for-loop.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 8 '06 #18

P: n/a
Noah Roberts wrote:
>
Evan wrote:
>Java has something that's arguibly better, which is a foreach loop.
http://java.sun.com/j2se/1.5.0/docs/...e/foreach.html

I say it's better because to use std::for_each you have to pass a
functor that does what you want in the third parameter, which means
that if you don't have one ready you either have to go off and write a
function first, or use boost::lambda (which can't always give you what
you want). No such requirement for Java's, because it's just a loop. At
the same time, if you DO have a function handy, Java's syntax is
essentially no more weildy than std::for_each.

It's really a completely different construct. Two strengths of C++'s
version are:

1) can be called on any range of data not just a complete collection
That can be accomplished by providing an alternative interface to the same
underlying collection.
2) can be called on a variety of constructs that are not collections,
has a more general interface.
The Java thing to do would be "slap an interface on it" or "wrap it up in a
collection interface". The big difference as I see it is that
std::for_each takes functionality as an argument, whereas the conventional
for-each construct has a body consisting of a block of code.
As you said, there is boost::lambda
IMO, boost::lambda is a path to becoming an academic niche language.
but there is also boost::bind or
tr1::bind that will perform better in many situations.
That is something worth looking into.
If you want something more closely resembling a foreach loop found in
Java, Perl, etc... then have a look at BOOST_FOREACH

http://www.boost.org/regression-logs...l/foreach.html

I'm not sure what the fate of the proposed C++ for_each core language
extension will be, but from what I've seen, it's the only fully satisfying
approach.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 8 '06 #19

P: n/a

Steven T. Hatton wrote:
for(unsigned i=0; i < coll.size();++i) coll[i]->rotate(m);
std::for_each(coll.begin(), coll.end(),
boost::bind(&ContainedClass::rotate, _1, m));

Dec 8 '06 #20

P: n/a
[snip]
As you said, there is boost::lambda

IMO, boost::lambda is a path to becoming an academic niche language.
I'm in academia, so that's okay. ;-)

On a more serious note, why? Most compliers now are good enough to
support it. Is the implementation poor? Is it slow or bloaty or
something? It seems like it would be useful for a fair number of times;
I don't see why you wouldn't want to use it.

Evan

Dec 8 '06 #21

P: n/a
Evan wrote:
[snip]
As you said, there is boost::lambda

IMO, boost::lambda is a path to becoming an academic niche language.

I'm in academia, so that's okay. ;-)

On a more serious note, why? Most compliers now are good enough to
support it. Is the implementation poor? Is it slow or bloaty or
something? It seems like it would be useful for a fair number of times;
I don't see why you wouldn't want to use it.
It's the same sentiment that struck me when I looked at the example on page
100 of TC++SL today:
pos = find_if(coll.begin(), coll.end(),
compose_f_gx_hx(logical_or<bool>(),
bind2nd(equal_to<int>(),25),
bind2nd(equal_to<int>(),35)));

I looked at that and thought to myself: 'didn't we already have a
programming language?'

If you want an esoteric programming language try this:

\[Rho] = 10;
\[Theta] = \[Pi]/5;

basis[\[Theta]_, \[Rho]_] :=
Arrow @@ Displacement[#, \[Rho], o] & /@ {\[Theta], \[Theta] + \[Pi]/2}

\[Epsilon][\[Theta]_, \[CurlyEpsilon]_, \[Gamma]_] /;
Mod[\[Theta], \[Gamma]] == 0. := \[CurlyEpsilon]
\[Epsilon][\[Theta]_, \[CurlyEpsilon]_, \[Gamma]_] /;
Mod[\[Theta], \[Gamma]] != 0. := 0

tac[\[Theta]_, \[Rho]_, \[Gamma]_] /; Mod[\[Theta], \[Gamma]] == 0. :=

Text[\[Pi]/2 - \[Theta]
, \[Rho] UR[\[Theta]]
, -1.5UR[\[Theta]]
, TextStyle -{FontSize -16, FontWeight -"Bold"}
]

tac[\[Theta]_, \[Rho]_, \[Gamma]_] /; Mod[\[Theta], \[Gamma]] != 0. := {}

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 8 '06 #22

P: n/a

Steven T. Hatton wrote:
Nothing wrong with creating a new class to perform an operation which can
easily be done in one line of code, and not even eliminating the original
line of code? There are times when it makes sense to use a visitor pattern
with function objects, but there are also many times when it serves no
other purpose than the complicate the code.
Yeah!

Hows about this. Grabs fixed size arrays and turns them into containers
and does compile time loop unrolling ;-)

(Uses later version of my Quan lib which I havent got round to updating
on sourceforge for a while... whatever)

Can also work on arbitrary transform matrices of course, but lets keep
it simple...

#include <quan/two_d/out/vect.hpp>
#include <quan/out/angle.hpp>
#include <quan_matters/src/constant.cpp>
#include <quan_matters/src/angle.cpp>
#include <quan/out/length.hpp>
#include <algorithm>
#include <vector>
#include <boost/static_assert.hpp>
#include <iterator>

// class to adapt a static array ( ar[N])
// for use as a container
// inpired by a recent post on comp.lang.c++.moderated
// who I will be happy to acknowledge
// if I can find it
template <typename T,int N>
class array_wrapper{
T * data_ ;
public:
const static std::size_t size = N;
array_wrapper(T (&a) [N]): data_(a){}
typedef T * iterator;
typedef T const * const_iterator;
iterator begin() {return data_;}
const_iterator begin()const {return data_;}
iterator end() {return data_ + N;}
const_iterator end()const {return data_ + N;}
template<int N1>
T& at(){ return data_[N1];}
T const & at()const{ return data_[N1];}
};

// compile time loop unrolling impl
template <int N>
struct for_x_in_wrapper;

template <>
struct for_x_in_wrapper<0>{
template <typename ArrayWrapper, typename F>
void operator()(ArrayWrapper& a, F const & f)const
{
f(a.at<0>());
}
};

template <int N>
struct for_x_in_wrapper{
template<typename ArrayWrapper, typename F>
void operator()(ArrayWrapper& a, F const & f)const
{
BOOST_STATIC_ASSERT(( ArrayWrapper::size >= N ) );
for_x_in_wrapper<N-1prev;
prev(a,f);
f(a.at<N>());
}
};

template <typename T,int N,typename F>
void for_each(array_wrapper<T,N& ar,F const & f)
{
for_x_in_wrapper<N-1ff;
ff(ar,f);
}

template <typename T,int N,typename F>
void for_each(T (&ar)[N],F const & f)
{
array_wrapper<T,Narw(ar);
for_each(arw,f);
}

// functor to rotate a vector
// calls sin, cos once irrespective of
// number of vertices
struct rotate{

rotate(double const & angle)
: cos_theta (std::cos(angle)), sin_theta(std::sin(angle)){}
double cos_theta, sin_theta;
template <typename Vect>
Vect & operator()(Vect & in)const
{
in = in * cos_theta + perp_vector(in) * sin_theta;
return in;
}
};

// functor to translate a vector
template <typename T>
struct translate{

translate(quan::two_d::vect<Tconst & trans_in)
: trans(trans_in){}
quan::two_d::vect<Ttrans;
template <typename Vect>
Vect & operator()(Vect & in)const
{
return in += trans;
}
};

// combine above
template <typename T>
struct point_rotate{

translate<Tto_origin;
rotate do_rotate;
translate<Tfrom_origin;
point_rotate(quan::two_d::vect<Tconst & translation,double angle)
:
to_origin(-translation),do_rotate(angle),from_origin(translat ion){}

template <typename Vect>
void operator()(Vect & in)const
{
to_origin(in);
do_rotate(in);
from_origin(in);
}
};

// rotate_by_point adaptor for static arrays
template <typename T, int N, typename Point,typename Angle>
void rotate_by_point(T (&ar)[N], Point const & point, Angle const &
angle)
{
array_wrapper<T,Narw(ar);
for_each(arw,point_rotate<typename Point::value_type>(point,angle));
}

struct output{
std::ostream & os;
output(std::ostream & os_in):os(os_in){}
template <typename T>
void operator()(T const & t)const
{
os << t <<'\n';
}
};

int main()
{
std::cout.setf(std::ios_base::fixed,std::ios_base: :floatfield);
std::cout.precision(2);
typedef double d;
std::cout << "using 2d vects of doubles\n";
quan::angle::rad angle = quan::angle::pi/2;
using quan::two_d::vect;

vect<dbox[] = {
vect<d>(0,0),
vect<d>(1,0),
vect<d>(1,1),
vect<d>(0,1)
};

for_each(box,output(std::cout));
vect<dpoint(2,0);
std::cout << "rotation angle = " << quan::angle::deg(angle) <<'\n';
std::cout << "rotation point = " << point <<'\n';
rotate_by_point(box,point,angle);
for_each(box,output(std::cout));

// works for any type of points...
std::cout << "\n Now using 2d vects of length::mm\n";
typedef quan::length::mm mm;
vect<mmbox_mm[] = {
vect<mm>(mm(0),mm(0)),
vect<mm>(mm(1),mm(0)),
vect<mm>(mm(1),mm(1)),
vect<mm>(mm(0),mm(1))
};

for_each(box_mm,output(std::cout));
vect<mmpoint_mm(mm(1),mm(1));
std::cout << "rotation angle = " << quan::angle::deg(angle) <<'\n';
std::cout << "rotation point = " << point_mm <<'\n';
rotate_by_point(box_mm,point_mm,quan::angle::pi/2);
for_each(box_mm,output(std::cout));

return 0;
}

output:

using 2d vects of doubles
[0.00, 0.00]
[1.00, 0.00]
[1.00, 1.00]
[0.00, 1.00]
rotation angle = 90.00 deg
rotation point = [2.00, 0.00]
[2.00, -2.00]
[2.00, -1.00]
[1.00, -1.00]
[1.00, -2.00]

Now using 2d vects of length::mm
[0.00 mm, 0.00 mm]
[1.00 mm, 0.00 mm]
[1.00 mm, 1.00 mm]
[0.00 mm, 1.00 mm]
rotation angle = 90.00 deg
rotation point = [1.00 mm, 1.00 mm]
[2.00 mm, 0.00 mm]
[2.00 mm, 1.00 mm]
[1.00 mm, 1.00 mm]
[1.00 mm, 0.00 mm]

regards
Andy Little

Dec 8 '06 #23

P: n/a

Evan wrote:
[snip]
As you said, there is boost::lambda
IMO, boost::lambda is a path to becoming an academic niche language.

I'm in academia, so that's okay. ;-)

On a more serious note, why? Most compliers now are good enough to
support it. Is the implementation poor? Is it slow or bloaty or
something? It seems like it would be useful for a fair number of times;
I don't see why you wouldn't want to use it.
I've considered completely ignoring its existance. Two
problems...first it can be quite abused so that your C++ code looks
more like lisp. I don't dig that too much but it is remenicient of
Java's ability to create classes on the fly inside of function calls.
Second, it has some technical problems that make it much less pleasant
to use than boost::bind.

It can be useful though to create very short statements inside of an
algorithm call without the need to create a function, functor, or
implement the algorithm by hand...and algorithms go beyond debating
whether to use for_each or a for loop.

Dec 8 '06 #24

P: n/a
kwikius wrote:
>
Steven T. Hatton wrote:
>Nothing wrong with creating a new class to perform an operation which can
easily be done in one line of code, and not even eliminating the original
line of code? There are times when it makes sense to use a visitor
pattern with function objects, but there are also many times when it
serves no other purpose than the complicate the code.

Yeah!

Hows about this. Grabs fixed size arrays and turns them into containers
and does compile time loop unrolling ;-)
My compiler will do that for me without templates.
(Uses later version of my Quan lib which I havent got round to updating
on sourceforge for a while... whatever)

Can also work on arbitrary transform matrices of course, but lets keep
it simple...
[snip]

I'll have to give that further thought. I have to wonder how much of that
is dependent on the fact that the code is template code. I hope this is
the right version. I haven't looked at this in quite some time:

template <typename T>
struct Inverse_T {
Inverse_T(const T& t_=0):_t(&t_) {}
operator T() const { return *_t; };
const T* _t;
};

template <typename T, size_t S>
inline boost::array<boost::array<T, S>, S>
operator*( const boost::array<boost::array<T, S>, S>& lhs,
const boost::array<boost::array<T, S>, S>& rhs ) {

boost::array<boost::array<T, S>, Sret;
boost::array<boost::array<Inverse_T<T>, S>, Sinv;

for(size_t i = 0; i < lhs.size(); i++) {
for(size_t j = 0; j < lhs.size(); j++) {
inv[i][j] = Inverse_T<T>(rhs[j][i]);
}
}

for(size_t i = 0; i < lhs.size(); i++) {
for(size_t j = 0; j < lhs.size(); j++) {
ret[i][j]=0;
for(size_t ii=0; ii < lhs.size(); ii++) {
ret[i][j] += lhs[i][ii] * inv[j][ii];
}
}
}
return ret;
}
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 8 '06 #25

P: n/a

Steven T. Hatton wrote:
kwikius wrote:

Steven T. Hatton wrote:
Nothing wrong with creating a new class to perform an operation which can
easily be done in one line of code, and not even eliminating the original
line of code? There are times when it makes sense to use a visitor
pattern with function objects, but there are also many times when it
serves no other purpose than the complicate the code.
Yeah!

Hows about this. Grabs fixed size arrays and turns them into containers
and does compile time loop unrolling ;-)

My compiler will do that for me without templates.
Sure, but it won't do a worse job with more compile time info and will
often do a better one.

<..>
I'll have to give that further thought. I have to wonder how much of that
is dependent on the fact that the code is template code. I hope this is
the right version. I haven't looked at this in quite some time:
<..>

You'll probably exceed some compiler limit if you tried to unroll all
that of course, but all is not lost, just do it for the inner loop(s).
Not sure if that will work or not.. whatever Here is stuff I was
working on recently:

http://tinyurl.com/v9qwm
These matrices are typed ie tuples, which means that you can put
arbitrary compile time 'static' values particularly for zeros and ones,
which optimises away many calcs to no-ops. This can result in a
reduction of 1/5 to 1/10 of the calcs on runtime values. There is a
lot of potential there to rock 3D games etc, but I don't have time to
work on it properly ..

Needs a compiler like VC8.0 or gcc4.0 . VC7.1 runs out of steam on this
stuff.

regards
Andy Little

Dec 8 '06 #26

P: n/a
Noah Roberts wrote:
>
Evan wrote:
>[snip]
As you said, there is boost::lambda

IMO, boost::lambda is a path to becoming an academic niche language.

I'm in academia, so that's okay. ;-)

On a more serious note, why? Most compliers now are good enough to
support it. Is the implementation poor? Is it slow or bloaty or
something? It seems like it would be useful for a fair number of times;
I don't see why you wouldn't want to use it.

I've considered completely ignoring its existance. Two
problems...first it can be quite abused so that your C++ code looks
more like lisp. I don't dig that too much but it is remenicient of
Java's ability to create classes on the fly inside of function calls.
That, IMO, is actually superior to boost::lambda. At least the code is, for
the most part, "normal".
Second, it has some technical problems that make it much less pleasant
to use than boost::bind.

It can be useful though to create very short statements inside of an
algorithm call without the need to create a function, functor, or
implement the algorithm by hand...and algorithms go beyond debating
whether to use for_each or a for loop.
I'm trying to figure out if it would be possible to create a generic
non-template abstract Function class that can be used as a base class for
local functors which could be passed to STL algorithms with a static_cast,
and still get the behavior of the derived functor class. I haven't tried
writing out the code. It's just an idea I've been meaning to try.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 9 '06 #27

P: n/a

Steven T. Hatton skrev:
Evan wrote:
[snip]
As you said, there is boost::lambda

IMO, boost::lambda is a path to becoming an academic niche language.
I'm in academia, so that's okay. ;-)

On a more serious note, why? Most compliers now are good enough to
support it. Is the implementation poor? Is it slow or bloaty or
something? It seems like it would be useful for a fair number of times;
I don't see why you wouldn't want to use it.

It's the same sentiment that struck me when I looked at the example on page
100 of TC++SL today:
pos = find_if(coll.begin(), coll.end(),
compose_f_gx_hx(logical_or<bool>(),
bind2nd(equal_to<int>(),25),
bind2nd(equal_to<int>(),35)));
But boost lambda was made exactly to avoid the code above. You simply
write:

pos = find_if(coll.begin(), coll.end(),_1 == 25 or _1 == 35);

So your argumentation makes no sense at all.

/Peter
[snip]

Dec 9 '06 #28

P: n/a
kwikius wrote:
>
Steven T. Hatton wrote:
>kwikius wrote:
>
Steven T. Hatton wrote:

Nothing wrong with creating a new class to perform an operation which
can easily be done in one line of code, and not even eliminating the
original
line of code? There are times when it makes sense to use a visitor
pattern with function objects, but there are also many times when it
serves no other purpose than the complicate the code.

Yeah!

Hows about this. Grabs fixed size arrays and turns them into containers
and does compile time loop unrolling ;-)

My compiler will do that for me without templates.

Sure, but it won't do a worse job with more compile time info and will
often do a better one.

<..>
>I'll have to give that further thought. I have to wonder how much of
that
is dependent on the fact that the code is template code. I hope this is
the right version. I haven't looked at this in quite some time:

<..>

You'll probably exceed some compiler limit if you tried to unroll all
that of course, but all is not lost, just do it for the inner loop(s).
Not sure if that will work or not.. whatever Here is stuff I was
working on recently:

http://tinyurl.com/v9qwm
These matrices are typed ie tuples, which means that you can put
arbitrary compile time 'static' values particularly for zeros and ones,
which optimises away many calcs to no-ops. This can result in a
reduction of 1/5 to 1/10 of the calcs on runtime values. There is a
lot of potential there to rock 3D games etc, but I don't have time to
work on it properly ..

Needs a compiler like VC8.0 or gcc4.0 . VC7.1 runs out of steam on this
stuff.

regards
Andy Little
I need to find time to review all this. What the example I posted is
supposed to do is multiply two arbitrarily sized conferment tensors. I
don't guarantee that it works correctly, though I believe it does. I just
posted it to show that I have done a bit with templates, and understand
that they can be useful.

I am also aware that they are not the only viable approach to creating
highly adaptive libraries. There's nothing intrinsic to C++ which prevents
the use of an object-based "core" library similar to what Java uses.
AAMOF, C++ may even have some significant advantages when it comes to
creating and using such a library.

I understand that there are trade-offs in taking such an approach. I can't
say that I clearly understand what those trade-offs are. I wonder if
anybody does. Unfortunately the question often devolves to little more
than zealotry.

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 9 '06 #29

P: n/a

Steven T. Hatton wrote:
I understand that there are trade-offs in taking such an approach. I can't
say that I clearly understand what those trade-offs are. I wonder if
anybody does. Unfortunately the question often devolves to little more
than zealotry.
I think the choice is simplified by asking the question:

Is such and such information available (and useable) at compile time?

If it is try to do that computation at compile time as possible, which
means generally using templates. That is my approach.

IOW templates represent polymorphism, but at compile time, while
virtual functions and so on represent polymorphism at runtime. Given
the choice I generally go for the compile time polymorphism option. The
only potential trade off may be code duplication, however once you get
to a stage where eveything is inlined and optimised away ( which
templates help with as its basically compiler friendly info) even this
is arguable.

regards
Andy Little

Dec 9 '06 #30

P: n/a
kwikius wrote:
>
Steven T. Hatton wrote:
>I understand that there are trade-offs in taking such an approach. I
can't
say that I clearly understand what those trade-offs are. I wonder if
anybody does. Unfortunately the question often devolves to little more
than zealotry.

I think the choice is simplified by asking the question:

Is such and such information available (and useable) at compile time?

If it is try to do that computation at compile time as possible, which
means generally using templates. That is my approach.
There's also a question of whether saving a few clock cycles is worth a
couple hours of programming. Sometimes it is, sometimes it isn't. Of
course there's noting to say templates aren't the easier solution in some
cases.
IOW templates represent polymorphism, but at compile time, while
virtual functions and so on represent polymorphism at runtime. Given
the choice I generally go for the compile time polymorphism option. The
only potential trade off may be code duplication, however once you get
to a stage where eveything is inlined and optimised away ( which
templates help with as its basically compiler friendly info) even this
is arguable.
For me the trade-off is usually in flexibility. Scene graphs and windowing
hierarchies are the examples which come to mind. In both situations it's
convenient to stick similar things together in arbitrary arrangements which
may be determined at run time. I know flow control via RTTI is typically
frowned upon by people whose opinions I hold in high regard. Nonetheless,
it is the essence of how many scene graph technologies are implemented.
IRIS Inventor is the example used in GoF for a visitor pattern implemented
in C++. I believe that is from the same SGI that brought us the STL.

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 9 '06 #31

P: n/a

Steven T. Hatton wrote:
For me the trade-off is usually in flexibility. Scene graphs and windowing
hierarchies are the examples which come to mind.
One doesnt preclude the other of course::

struct node{virtual~node();};

struct branch : virtual node {};

template <typename Data>
struct leaf : virtual node{};

regards
Andy Little

Dec 9 '06 #32

P: n/a
kwikius wrote:
>
Steven T. Hatton wrote:
>For me the trade-off is usually in flexibility. Scene graphs and
windowing hierarchies are the examples which come to mind.

One doesnt preclude the other of course::

struct node{virtual~node();};

struct branch : virtual node {};

template <typename Data>
struct leaf : virtual node{};

regards
Andy Little
I have to refine my thinking regarding programming with RTTI. I didn't
realize there was a significant difference between using virtual functions
and using dynamic casts. According to this document, dynamic_cast<is
very expensive ~5to10 times more expensive than virtual function calls.

http://www.research.att.com/~bs/performanceTR.pdf

That makes me wonder why I see as many dynamic_cast<>s as I do in some code.
What I posted earlier was making the incorrect assumption that the two
methods incurred comparable overhead.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 9 '06 #33

P: n/a
Steven T. Hatton wrote:
kwikius wrote:

Steven T. Hatton wrote:
I understand that there are trade-offs in taking such an approach. I
can't
say that I clearly understand what those trade-offs are. I wonder if
anybody does. Unfortunately the question often devolves to little more
than zealotry.
I think the choice is simplified by asking the question:

Is such and such information available (and useable) at compile time?

If it is try to do that computation at compile time as possible, which
means generally using templates. That is my approach.

There's also a question of whether saving a few clock cycles is worth a
couple hours of programming. Sometimes it is, sometimes it isn't. Of
course there's noting to say templates aren't the easier solution in some
cases.
There's also a question of whether the template approach will let you
detect errors at compile time. One of my favorite TMP examples (and one
of the more complicated examples that I can still understand) is the
one from the book I have on it and the Boost docs where they create a
set of templates that do dimensional analysis at compile time to make
sure that units are done correctly.

It's a rather more complicated approach than doing the same thing
"traditionally", but even if the performance were the same it's
probably worth it because it lets you catch a certain class of errors
during compilation rather than at runtime.

(The utility of the error messages your compiler will give you if you
do make a mistake is another matter...)

Evan

Dec 9 '06 #34

P: n/a

Steven T. Hatton wrote:
kwikius wrote:

Steven T. Hatton wrote:
For me the trade-off is usually in flexibility. Scene graphs and
windowing hierarchies are the examples which come to mind.
One doesnt preclude the other of course::

struct node{virtual~node();};

struct branch : virtual node {};

template <typename Data>
struct leaf : virtual node{};

regards
Andy Little
I have to refine my thinking regarding programming with RTTI. I didn't
realize there was a significant difference between using virtual functions
and using dynamic casts. According to this document, dynamic_cast<is
very expensive ~5to10 times more expensive than virtual function calls.

http://www.research.att.com/~bs/performanceTR.pdf

That makes me wonder why I see as many dynamic_cast<>s as I do in some code.
What I posted earlier was making the incorrect assumption that the two
methods incurred comparable overhead.
Wll you can also use the curiously recurring template pattern. Examples
are Microsoft ATL and WTL on sourceforge.

You can of course combine the whole shebang. templates, virtual
functions and multiple inheritance and CRTP. In the above you might
use a virtual is_branch and is_leaf function so you dont need the
dynamic cast unless it will succeed. And of course in the above you can
have nodes that are both branches and leaves ;-)

regards
Andy Little

Dec 9 '06 #35

P: n/a

"Steven T. Hatton" <ch********@germania.supwrote in message
news:4r******************************@speakeasy.ne t...
Victor Bazarov wrote:
>Steven T. Hatton wrote:
>>[.. gripe, gripe ..]
Will a programmer who knows how to use templates very well be
significantly more productive than one who sticks to the traditional
OOP aspects of C++?

In what team, doing what? IOW, yes, if using templates is what is
required from that programmer. No, if using templates is not in
his/her everyday activity.

However, consider what you yourself wrote: while reading the book on
templates you have discovered how much you didn't know of the "core"
C++ language. It is conceivable that the "one who sticks to the
traditional OOP aspects of C++" is actually not as knowledgeable
where the "core" C++ is concerned than one thinks one is.

Can you learn to read a human language and claim proficiency in it
without, say, being able to talk? There were people who were very
versed in a foreign language without knowing how the words they read
or write are pronounced. Are they missing much? I don't know. How
do you actually measure that? What I can say is that their knowledge
is incomplete and very artificial. They are definitely missing some
jokes based on how words are pronounced... Of course, if they stick
to the traditional scientific language, they can even be productive
in an environment where they don't need to talk or understand speech
or understand jokes based on word play.

Does that answer your concerns?

V
Not really. But that's probably because my concerns are such that there
really is no answer than "there's only one way to find out". I guess I'm
feeling discouraged by the number of idiosyncracies I have learned lurk
under the guise of templates. The way I see things right now, template
programming is kind of like programming the compiler to write code rather
than simply using the compiler to compile the code we write. It requires
a
fairly good understanding of the compilation stages in order to do
anything
beyond the basics. The knowledge and understanding will likely be useful
regardless of whether templates themselves prove useful to me.

I do have to ask myself, however, what do I get out of creating templates
which adapt to the type I instantiate them with in order to create
functions or classes? How much /reuse/ am I really likely to get out of a
template? One exercise I undertook several months ago was to create my
own
vector math library using templates. You helped me work out some of the
trickier parts, you may recall. So now I have a vector math library which
is some ways is better than any others I have seen. I can instantiate the
templates with float or double. For what I'm doing, I almost always use
float because its faster, leaner, and sufficiently precise.
How much reuse you're gonna get out of using templates cannot be answered in
such a general way. They will certainly not be the solution to all your
problems and sometimes they might be overused. You will find a large group
of people programming in C++ without really having a clue about templates.
They will also manage to do their task in one way or another, but that is
exactly the point. Templates allow you to do things that are not as easily
(or sometimes not at all) accomplished as doing them without the use of
templates.

In the case of your vector math lib it is arguable whether it was worth the
effort and that really depends. Still, you now have a tool at your hand
which can switch from float to double precision in no time and one day you
might need that precision.
But let's forget for a moment the obvious applications of templates in the
implementation of collections. There are things like concept checking
(probably quite important and useful for library designers), several design
patterns and also meta-template optimized structures that would not work or
only with limitations, without templates. Yet, I do agree that these topics
are quite advanced and require a sound knowledge of how a C++ compiler
works.

Thus, one should first acquire a profound knowledge of the "core" of the
language before considering to venture off into the area of advanced
template programming. But you can somehow compare it to a "real human"
language - it's one thing to read & write English at a level where you can
communicate with others and find your way around. However, reading &
understanding good literature will increase your appreciation of the subtle
nuances of the language and certainly improve your proficiency in the long
run.

Cheers
Chris


Dec 10 '06 #36

This discussion thread is closed

Replies have been disabled for this discussion.