Are C++ templates a precompiler thing?

J

JohnQ

Gianni Mariani said:
JohnQ wrote:
...

It's just an example of a problem that has been solved many times and it
degenerates into alot of tedious code. This is a case where templates
simplify the code dramatically, if you know how to use them. The code in
this case is a simple transformation from the specification.


Containers now, then smart pointers, special iterators etc etc. It's a
powerful tool if you learn to use it.

When I say "containers" I mean the whole ball of wax:
containers/iterators/algorithms, things like smart pointers etc. It's all
very basic stuff that preprocessor templates can handle. And those are "the
general case". No need to make everything complex IMO. Make special things
for the special cases and don't impact the general case is my motto.
Sometimes I need a truck to bring things home from Home Depot, so I rent
one. Most times I just use my car. I wouldn't want to drive a truck all the
time, or purchase one, just because I need one once a year.
That's a "reason" ?

You clipped the context, so here it is:

"Templates do have a learning curve. You do have to think of your code
in a more generic fashion."

To which I'll respond:

Templates shouldn't be (and are not) difficult at all. It's the C++
"almighty powerful" ones that can be "hard" (take time to learn). But that's
ok, because 99% of the time, you don't need the specialized functionality.
C++ templates are a language within a language rather than just "generics".
I prefer the more general definition and basic implementation. (The K.I.S.S.
principle). When I need a truck, I'll rent one. On a daily basis though,
I'll stick to driving a car. Realize too that if you introduce C++-specific
things deeply into your code, your HIGHLY-C++-specific designs aren't going
to be portable to other languages/tools (say java or .net or Pascal or
whatever). _You_ may think that it's OK to use all the elements of C++
everywhere and all the time and as much as possible, I, OTOH, am at the
opposite end to that. Your statement "You do have to think of your code in a
more generic fashion." is not prudent advice IMO if you mean it like "see
where you can use templates and try to find ever increasing places in which
to use them". I would rather say: be judicious in the use of language
facilities, always, and prefer simple constructs and mechanisms over complex
ones.

K, nuff said (I hope).

John
 
J

JohnQ

Ian Collins said:
I ask again, show us a map container implemented with macros, time to
put up or shut up.

There's another post I just made that shows the concept using an list link
(note that it is not actual code from any library that I use, but is rather
just for illustrative purposes). None of this stuff is "top secret" BTW.
Though I can't post my actual container code here, you should be able to see
the concept quite clearly. Again, it's "old hat" stuff if you've been a C++
user from the beginning. See one of my latest posts in this thread for the
"pattern".

John
 
O

Old Wolf

Templates are a part of the C++ language. They are not
preprocessor macros.

'Preprocessor macros' are also a part of C++ language.
In fact, translation phases 1-7 are what people normally
mean when the say 'the preprocessor'. Phase 8 involves
instantiating templates.

It's just a convention that compiler vendors supply
distinct executables to perform the various translation
phases.
 
I

Ian Collins

JohnQ said:
Below is the general concept of using the preprocessor for templates:

(Class functions just for illustration cuz the data members in a real
implementation would probably be public. Functions can be used to
get or set. obj does not have to be a pointer.)

#define concat2(x,y) x##y
#define slink(T) concat2(slink_,T)

// The "template" below is not a "macro" (well it is, but it isn't)
// (it's just a code generator).
//
#define DeclareSLink(T)\
class slink(T)\
{\
T* obj;\
slink(T)* next;\
\
public:\
void slink(T)(T* o, slink(T)* nxt=0)\
:eek:bj(o), next(nxt) {}\
\
T*& Obj(){ return obj; } \
slink(T)*& Next(){ return next; }\
};
So you have a more verbose way to declare a simple "template" in global
scope. What does this gain you over the more concise standard C++
template definition?
 
J

JohnQ

Ian Collins said:
So you have a more verbose way to declare a simple "template" in global
scope. What does this gain you over the more concise standard C++
template definition?

There's no limitation of global-only scope. The standard templates are not
much more concise.

What does the above get me, well control of the template system
implementation. A proof of concept that adequacy can be had with a
preprocessor-based implementation. (One thing that used to irk me with C++
templates is the way the compiler would generate stuff automatically. With
the above, I know that if I didn't use a DeclareX construct, it hasn't been
generated). The exercise above can be extended to actually hacking an
existing preprocessor to implement templates without all the macro-ish
backslashes (it's already been done with C++ template style syntax). Then,
you have a basic templates implementation dirt cheap, and one that you can
control.

To me, "templates" means the kind of thing the preprocessor does (text
substitution) and using it to generate typed code. Once it gets beyond that
concept, it's a different (C++-specific concept) animal, IMO. I like
templates to be implemented in the pre-compilation phases. If I ever wanna
implement that new fangled language I'm always yapping about, I'll be way
ahead by not having created dependence on things deep inside of commercial
C++ compilers that I would have a hard time reproducing (if possible at
all).

John
 
J

JohnQ

Old Wolf said:
'Preprocessor macros' are also a part of C++ language.
In fact, translation phases 1-7 are what people normally
mean when the say 'the preprocessor'. Phase 8 involves
instantiating templates.

It's just a convention that compiler vendors supply
distinct executables to perform the various translation
phases.

Are you saying that the phases only are specified and that they are not
associated with things like "preprocessor" and "compiler". (I can then make
a conforming implementation using preprocessor-based templates?).

John
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

Realize too that if you introduce C++-specific
things deeply into your code, your HIGHLY-C++-specific designs aren't going
to be portable to other languages/tools (say java or .net or Pascal or
whatever). _You_ may think that it's OK to use all the elements of C++
everywhere and all the time and as much as possible, I, OTOH, am at the
opposite end to that. Your statement "You do have to think of your code in a
more generic fashion." is not prudent advice IMO if you mean it like "see
where you can use templates and try to find ever increasing places in which
to use them". I would rather say: be judicious in the use of language
facilities, always, and prefer simple constructs and mechanisms over complex
ones.

Just a though but isn't the preprocessor quite unportable too? The
only languages I know of that have it is C and C++, and even if some
other language have one it's probably not 100% compatible with the one
in C++. Sure you can run it through the C++ preprocessor first and
then compile it with your Java (or whatever) compiler, but if you have
the C++ preprocessor you probably have the C++ compiler and could just
as well use that. And I haven't even mentioned the problem when others
want to compile your Java code that first needs to go through a
preprocessor.
 
J

JohnQ

Realize too that if you introduce C++-specific
things deeply into your code, your HIGHLY-C++-specific designs aren't
going
to be portable to other languages/tools (say java or .net or Pascal or
whatever). _You_ may think that it's OK to use all the elements of C++
everywhere and all the time and as much as possible, I, OTOH, am at the
opposite end to that. Your statement "You do have to think of your code in
a
more generic fashion." is not prudent advice IMO if you mean it like "see
where you can use templates and try to find ever increasing places in
which
to use them". I would rather say: be judicious in the use of language
facilities, always, and prefer simple constructs and mechanisms over
complex
ones.

"Just a though but isn't the preprocessor quite unportable too?"

(Oh, another one with special characters in their signature line huh).

I was thinking "portability of resulting containers" for example. Now that
is easy if one hasn't relied upon anything more than simple text
substitution to generate those containers. But if the containers rely upon
highly intricate compiler-based templates mechanisms, there will be big
problems in bringing the code to a new environment because the design is
entwined with the implementation (not based upon common language constructs
but rather specialized C++ ones).

John
 
G

Gavin Deane

I limit what templates can do by requiring of them that they can be
implemented simply.

JohnQ: Can templates be implemented the same way as macros - straight
text substitution?

Others: No - here are some examples of things you can do with
templates that you can't do with macros.

JohnQ: Oh no - I don't mean things that complex or specialised. What I
meant to ask was, "Can a limited subset of template capabilities be
implemented as straight text substitution? The subset is limited to
only those things that can be implemented as straight text
substitution."

To which the answer is obviously "yes", by definition. But it's a
somewhat pointless question, is it not?

Gavin Deane
 
J

James Kanze

OK, show us a map container implemented as macros.

Been there. Done that. It's ugly. You don't want to see it.

It's also relatively irrelevant. You can do a lot with textual
substitution, but it doesn't obey the same rules as templates.
My first AssocArray class, using generic.h, couldn't be
instantiated on a nested class, for example, since it token
pasted the class name to get the name of the "template"
instantiation. (Of course, that wasn't a problem then, since
the compiler didn't support nested classes yet anyway.)

If you really want an example of something that cannot be done
with macros, at all, try some of the template metaprogramming
stuff. Say, for example, std::distance (which selects different
algorithms according to the type of the iterator---note,
however, that my <generic.h> AssocArray was a hash table, and
used a traits class to specify how to calculate the hash code
and test for equality). But IMHO, that's not really the point.
The point is that even when used for something that could be
done using macros, templates don't behave like macros. In any
way, shape, form or fashion. There's no textual substitution
involved.
 
J

James Kanze

Can they be implemented that way though (early work did exactly that).

Then they're not templates. Basically, templates were added to
What's the diff?

They do two, fundamentally unrelated things. Templates are
integrated into the language, and operate on language level
entities, such as types and constant expressions. Macros
operate at an earlier level, on text.
I disagree. I'm leaning toward "they should be the same".
Beyond that (macros), templates become unwieldly.

That solution was tried. And failed. Have you ever actually
used <generic.h>?
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

(Oh, another one with an unconventional quoting style huh).


Did you mean the "ö"? Are you suggesting the poor fellow misspell his own
name???

And now I'm a poor fellow just because I'm born with a surname not
representable in 7 bit ASCII, I don't want to think about those poor
millions of Chinese people :)
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

"Just a though but isn't the preprocessor quite unportable too?"

(Oh, another one with special characters in their signature line huh).

I was thinking "portability of resulting containers" for example. Now that
is easy if one hasn't relied upon anything more than simple text
substitution to generate those containers. But if the containers rely upon
highly intricate compiler-based templates mechanisms, there will be big
problems in bringing the code to a new environment because the design is
entwined with the implementation (not based upon common language constructs
but rather specialized C++ ones).

I'm not quite sure I follow you here, do you mean that if one wanted
to port the code to another platform they should firs run it through
the preporcessor and take a look at the output to see how the
containers should be implemented. Now consider if this new platform/
language does not have a text-substituting facility like the
preprocessor and you have used your container for 15 different types,
that would mean that you would have to type 15 different
implementations of that container, no?

Oh, one of those few who *can* write their name in pure 7-bit ASCII.
 
J

James Kanze

"Gianni Mariani" <[email protected]> wrote in message

[...]
HP hacked a preprocessor (PCC) to provide probably the earliest template
implementation for C++.

HP never hacked the C++ preprocessor to provide templates. Get
your facts straight.

For as long as I've been using C++ (which goes back well before
templates were widespread), there was a file <generic.h>,
copyright AT&T (not HP---I was working on Sun machines at the
time), which contained a few of tricky defines which allowed
some pseudo-generic classes---my first AssocArrayOf (basically
map) was based on them. It was quite apparent, however, to
anyone that used them that they were not the solution, and that
something integrated into the language was necessary. I'm not
sure of the exact dates, and most of this I have from hearsay
(but from people who have actually worked very closely with the
people involved), but at one point, Stroustrup wrote a
preliminary definition of templates, and John Spicer implemented
an experimental version in CFront. Somehow (from what I
understand), this version got out the door, and became CFront
3.0, although it was never intended to be released by the
authors. It was rapidly replaced with version 3.0.1, which
corrected the bugs which made it totally unusable, but not much
else.

So: if you're talking about <generic.h>, it was macro based, it
came from AT&T, and it was found to be insufficient by just
about everyone who used it. And if you're talking about
templates, the first implementation was also at AT&T, it was
within CFront (which processed the pre-processor output), and
had nothing to do with the pre-processor.

[...]
If I just need to create containers and that is my only
interest in using templates, the specialized stuff you're
doing is, well specialized!

I've actually used <generic.h> in production code. For
containers and smart pointers. It doesn't work. That's why
templates were invented, because a pre-processor based solution
doesn't work.
 
J

James Kanze

"Erik Wikström" <[email protected]> wrote in message
Realize too that if you introduce C++-specific [...]
ones.
"Just a though but isn't the preprocessor quite unportable too?"
(Oh, another one with special characters in their signature line huh).

And who posts through Google, and who has a header line:
Content-Transfer-Encoding: quoted-printable
From other posts of mine (where I've suppressed the accented
characters), I think that this line is what is causing you
problems. I don't know where it is inserted; Google doesn't
seem to insert it when I post from home. But technically, it is
legal, even if there is no real reason for it to be there, and
it shouldn't cause any problems for your newsreader.

I'm going to try to find out where it is inserted in my case,
and get rid of it if I can. But you really should get your
newsreader fixed. As far as I can tell, you're the only one who
has this problem.
 
D

Dizzy

JohnQ said:
That's a good thing if you ask me though: "keeping them on a leash".

That's irrelevant to the original question.
Template functionality (not the complex C++ incarnation of them) can be
implemented in various ways.

If by "templates" you mean something else that ISO C++ template keyword and
it's related functionality then probably yes, however that's irrelevant to
the original question.
Reduction of complexity.

Nobody forces you to use them. Having them is an added bonus. You can just
use the preprocessor you are so found of.
I don't think I need that.

Again not relevant to the original question. The original question was,
quote: "Are C++ templates a precompiler thing?"

This was evolved into "can they be made" a precompiler thing and such. For
the first question you have an easy answer ("no because they are done by
the compiler right now"). For the second there seems to be impossible to
make it in the preprocessor without the compiler knowledge because of the
SFINAE and other template semantics. Of course you may not need those and
of course if your definition of templates resumes to just being some kind
of macros then you could do them with preprocessor macros. However
these "limited templates" are not the "C++ templates" from the original
question, which are much more rich in functionality.

You did say "C++ templates" which means the templates functionality of the
C++ language as a whole.
 
J

JohnQ

Lionel B said:
(Oh, another one with an unconventional quoting style huh).


Did you mean the "ö"? Are you suggesting the poor fellow misspell his own
name???

I only speak English and recognize the English alphabet, sowwwy. I suppose
you want newgroups to be Unicode?

John
 
J

JohnQ

"Just a though but isn't the preprocessor quite unportable too?"

(Oh, another one with special characters in their signature line huh).

I was thinking "portability of resulting containers" for example. Now that
is easy if one hasn't relied upon anything more than simple text
substitution to generate those containers. But if the containers rely upon
highly intricate compiler-based templates mechanisms, there will be big
problems in bringing the code to a new environment because the design is
entwined with the implementation (not based upon common language
constructs
but rather specialized C++ ones).

"I'm not quite sure I follow you here, do you mean that if one wanted
to port the code to another platform they should firs run it through
the preporcessor and take a look at the output to see how the
containers should be implemented."

Not really. Any sort of generics implementation is going to have to do code
generation. Assuming C++-style
built-into-the-compiler-in-highly-complex-ways is a deal breaker.

" Now consider if this new platform/
language does not have a text-substituting facility like the
preprocessor and you have used your container for 15 different types,
that would mean that you would have to type 15 different
implementations of that container, no?"

"Oh, one of those few who *can* write their name in pure 7-bit ASCII."

Making a case for Unicode? Note that my newsreader doesn't preprend the >
symbol to lines when someone uses the non-english characters in their
signature. Perhaps the Chinese should sign their posts in the gyphs of their
language too huh. And everyone should learn to read Chinese so that they
know what to call them. When in Rome...

John
 
L

Lionel B

And now I'm a poor fellow just because I'm born with a surname not
representable in 7 bit ASCII, I don't want to think about those poor
millions of Chinese people :)

Indeed!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top