Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

C/C++

Epicenter Johnny & typename Exposed


Feb03: C Programming

Al is DDJ's senior contributing editor. He can be contacted at [email protected].


Many years ago, the son of a friend came to me for some advice. John Fitz wanted to be a writer. He wanted to write stories like Stephen King writes and have them published. I was the closest thing to a professional writer he knew, and he thought I might have some advice that he could use to help him get started.

John was motivated, but he did not have the tools he needed to write. Or, at least, he did not have the tools that were available at that time. All John had was a typewriter and some paper. Sure, that was good enough for Hemingway, but this was 1987, and we'd come a long way.

There is almost always a computer in my shop looking to be given away or, in these days of such rapidly advancing technology, ready for the land fill. When John came to me for advice, I had upgraded to some kind of PC clone and had retired a very nice little CP/M machine with a video terminal and a couple of 5.25-inch diskette drives. I told John he needed a word processor if he wanted to be a writer in the 1980s. I gave him that little machine along with diskettes of CP/M and the Wordstar word processor. John took his new hardware and went off somewhere to begin writing the Great American Scary Novel. When John finally had enough narrative written to print, he got a printer and I helped him install it, no easy task back then. As I recall, I had to write a printer driver in 8080 assembly language and install it into the operating system. Easier than writing about the occult, I suppose, but every bit as scary.

Over the years, I heard from John occasionally. He told me he was still writing, still sending manuscripts to publishers, and still papering his walls with rejection notices. He maintained a day job, which allowed him to gradually upgrade to better hardware and software to use in his writing endeavors. John's resolve never waned. He never lost confidence in his own ability. He knew he had the right stuff. He kept plugging away.

A few weeks ago, John's dad brought me a present. It is the first published book authored by John Fitz, who autographed this copy just for me. The book is called Epicenter Johnny. Stephen King's breakthrough book was Carrie, about a girl who could use her mind to make fires break out. John's book is about a guy who can bring on earthquakes. If occult literature interests you, you can find Epicenter Johnny at Amazon.com. For me, it's a source of pride that someone I helped in a small way so many years ago stuck with it and found his way through the discouraging and frustrating maze one must navigate to get a book into print.

You might remember the MidiFitz project I published in this column several years ago. That project was named after John's dad, Johnny Fitz, my good friend and musical collaborator for over two decades. And so the circle remains unbroken.

What's in a typename

Speaking of books and publishers, I am writing yet another edition of my tutorial C++ book titled Teach Yourself C++ to be published under the MIS:Press imprint, owned (this year, at least) by Wiley. As usual, when shamelessly plugging my book, I remind readers not to mistake my work for those with similar titles. Other publishers, short on originality and eager to capitalize on my wildly successful series of books, appropriated my title and turned their authors loose. MIS:Press, being a kindly and benevolent publisher, declined to press the matter, wishing as King did (Rodney, not Stephen) that we can all just get along. Yeah, right. Consequently, there are at least three lines of computer books titled "Teach Yourself" something or other from three different publishers. Don't be fooled by imitations. Mine is the original. Those other guys are mere pretenders to the throne.

While doing research for this new edition, I went in search of lucid explanations of some of the more arcane language additions introduced by Standard C++. The C++ Standard document explains each such improvement with respect to how a compiler writer should implement them in a compliant compiler. But the Standard rarely explains why a particular feature exists, and it never provides more than a mere fragment of code to demonstrate a feature's operation, much less a code example that illustrates why the feature is needed in the first place. Not that it should. A programming language standard specification document only explains the language for compiler builders. It is up to others to explain its uses and rationales from a programmer's perspective, said others being distinguished computer book authors such as yours truly, whose mission it is to clear up the mysteries of the Standard.

One such mysterious feature is the typename keyword. Standard C++ added typename to the language to solve some semantic ambiguities introduced by the class template mechanism and to make template declarations more intuitive to the human reader. Typically, the Standard explains the grammar, syntax, and behavior of typename without explaining its purpose, which is not exactly intuitive.

I have a lot of C++ books. I pored through the more recent ones, those published since 1998 when Standard C++ became official, only to find a dearth of information about typename. Only three books in my library even attempt to explain it and none of them are C++ tutorials. Perhaps my library is already out of date. Since I'm only now getting around to updating my book, maybe all those other authors, including the ones who ripped off my title, are ahead of me. A trip to Books 'A' Million turned up a lot of very recent C++ titles and almost no information about typename. I spent the better part of an hour poring through every book, even the ones that promise to be complete, comprehensive treatments of C++. Very few books even mention typename, and those that do have almost no useful information about it. I won't mention any authors' names whose books are derelict in their coverage. I won't embarrass them that way. They know who they are.

The three books in my library that do try to explain typename are The C++ Programming Language, Third Edition (Addison-Wesley, 1997), by Bjarne Stroustrup; Effective STL (Addison-Wesley, 2001), by Scott Meyers; and Standard C++ IOStreams and Locales (Addison-Wesley, 2000), by Angelika Langer and Klaus Kreft. None of these books are C++ tutorials and, of the three, only the last one adequately explains why the C++ language needs typename. Stroustrup makes a good stab at it, but, typical of Stroustrup, he writes concisely for the expert rather than the novice. A C++ programmer would understand his explanation. A C++ student might not.

That third book, Standard C++ IOStreams and Locales, is an essential part of any C++ library. It is the only work I've seen that explains IOStreams at a detailed enough level that you can begin to see how you might use the library to its fullest potential. It is also the only work I've seen that addresses C++ locales in sufficient detail to get you started making a software system portable to many cultures. It explains typename only as an aside in a section that identifies new C++ language features.

So, if you are looking for a tutorial C++ book with comprehensive coverage, you know where to go. Sometime in early 2003, look for Teach Yourself C++, Seventh Edition. If you are unsure whether you are looking at my book or one of those feeble imitations, look in the index. If you find typename listed there, chances are you've got the right book. Assuming my name is on the cover that is. Those other guys wouldn't stoop to putting my name on their cover next to my title. Would they?

Template Ambiguities

To understand the ambiguities that typename addresses, you must understand typedef and public class members. Here's some background.

First, a program can define a new type name by using the typedef statement; see Example 1. The compiler treats the pint identifier in Example 1 as a type defined to be the same as a pointer to int. The program can now declare and use variables of type pint.

You can declare a typedef within a class definition as Example 2 shows. The iter typedef declaration in Example 2, which is a pointer to type Placecard in this case, is not in global or file scope. It is declared as a public member of the Placecard class. The program declares objects of type iter by qualifying the type reference with the name of the class that declares it and the scope resolution operator like this:

Placecard::iter pi;

The program now uses the pi variable just as it would a pointer to type Placecard. The compiler knows how to translate the typedef name Placecard::iter into a type that is, in this case, a pointer to Placecard.

Suppose you are building a class template that expects its parameterized class to declare a type named iter as Placecard does. That class template might look something like Example 3: The ambiguity in Example 3 might not be immediately obvious, but the compiler does not know what to do with this statement:

T::iter * y;

First, the compiler does not know what T is at this time because it has to parse the class template code without having seen an instantiation of the class template with a parameterized type. That is a normal circumstance with which the compiler routinely deals. Not knowing what T is, the compiler does not know what T::iter is, either. Because the compiler does not know that, it cannot tell whether the statement declares a pointer to type T::iter named y or is an expression that multiplies whatever T::iter is times whatever y turns out to be. If y is not defined in the current scope, the compiler reports an unidentified y. In either case, the compiler, does not know what to do with the statement, which it assumes is an expression.

To eliminate the ambiguity, the committee added the typename keyword. The class template and its member functions qualify all references to types defined in the parameterized type with the typename keyword as in:

typename T::iter * y;

When the compiler sees the typename keyword, it knows that what follows is a type and parses the code assuming a type name will be filled in by the instantiation.

Standard C++ requires the typename qualifier for all types referenced in a template that are defined in the templatized class even when no ambiguity would result from omitting it. Listing One (available electronically; see "Resource Center, page 5), demonstrates the use of typename in this manner. You can see the effect of not using typename in this manner by removing it from the code in Listing One and compiling the program with any of today's Standard C++ compliant compilers.

There are other kinds of expressions in class template member functions that would result in ambiguities that the typename keyword disambiguates. C++ syntax permits parentheses where you rarely see them:

int (num);

This statement declares an int variable named num. The parentheses are superfluous, but they are permitted. Suppose, however, that a class template member function contains this statement:

T::iter(num);

The compiler does not know whether this statement declares a variable named num of type T::iter, or calls a function named T::iter passing an argument named num, quite possible if there is a nonlocal variable of that name in the current scope when the class template is instantiated. The typename keyword corrects this ambiguity the same way it does the earlier example:

typename T::iter(num);

By requiring the typename qualifier for all references to types declared in the parameterized class, the Standard ensures that such ambiguities cannot occur.

At least, these are the arguments given to justify typename. Compilers that do nothing with template code until something in the program instantiates a parameterized object of the template class should not have this problem, and older compilers do, in fact, properly compile templates that refer to types declared in parameterized types without the typename keyword. Most contemporary C++ compilers instantiate templates when the program instantiates parameterized types. But Standard C++ anticipates better compiler implementations that will someday compile template code without knowing the parameterized type. The Standard also expects that template member functions do not have to be visible to the compiler whenever a parameterized type is declared. The Standard anticipates a time when template member functions can be compiled outside the scope of the code that uses them, even in independent translation units. Thus, the potential if not actual ambiguity and, thus, the requirement for typename.

I hope I got that explanation right. It's the best I can do given the available literature.

typename versus class

Given the introduction of typename into Standard C++, the committee decided to use it in templates where class was used to declare the parameterized types. Previous implementations of templates prior to the publication of the Standard C++ specification use the class keyword in their template declarations like this:

template<class T1, class T2>.

This syntax might be misleading because the actual parameterized types in an instantiation of a template can be classes, intrinsic types, pointers and references to things, and typedefs, many of which are not classes at all. Thus, Standard C++ allows the typename keyword instead of class in template declaration statements like this:

template<typename T1, typename T2>

Listing Two (available electronically) demonstrates typename instead of class in the template declaration statements for function templates and class templates.

Standard C++ could not simply replace class with typename in this context because too much existing code would have been broken. The template mechanism was in place in many implementations long before typename became part of the Standard specification. Whether you use class or typename in this context is a matter of preference. The experts are divided on whether you should use typename or class in template declarations.

In Effective STL, Scott Meyers says, "When I declare a formal type parameter for a template, I use typename instead of class...class and typename mean exactly the same thing, but I find that typename more clearly expresses what I usually want to say: that any type will do; T need not be a class."

In the other camp, in The C++ Programming Language, Third Edition, Bjarne Stroustrup says, "Being an indifferent typist and always short of screen space, I prefer the shorter: template <class T>..."

DDJ

Listing One

#include <iostream>

static int y;

template <class T>
class Table {
	typename T::iter t;
public:
	explicit Table(const typename T::iter& ti) : t(ti)
	{  }
	void position()
	{
		typename T::iter * y;
		y = &t;
		std::cout << (*y)->p;
	}
};
class Placecard {
public:
	typedef Placecard* iter;
	int p;
	Placecard(int pos) : p(pos)
	{ }
}
;
int main()
{
	Placecard pc(3);
	Table<Placecard> settable(&pc);
	settable.position();
	return 0;
}

Back to Article

Listing Two

#include <iostream>

template<typename T>
T DoubleValue(T value)
{
	return value * 2;
}

template<typename T1, typename T2>
class TwoThings {
	T1 thing1;
	T2 thing2;

	T1 thing3;
public:
	TwoThings(T1 tt1, T2 tt2)
	{
		thing1 = tt1;
		thing2 = tt2;
		thing3 = DoubleValue<T1>(tt1);
	}
	void display()
	{
		std::cout << thing1 << ' ' << thing2 << ' '
		<< thing3 << std::endl;
	}
};
int main()
{
	int a = 123;
	double b = 456.789;
	TwoThings<int, double> my2things(a, b);
	my2things.display();
	return 0;
}

Back to Article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.