Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents


Part Four: Cognizant Conversions

If the chapters in Part One were too easy, or those in Part Two were altogether too C-oriented for your tastes, or those in Part Three were too "in the small," fear not. Part Four will deliver on all counts. The material covered in these chapters is challenging, 100% C++, and covers some seriously "in the large" imperfections. To the cyclists among my audience, I would say: we're about to hit the Alps! In this part we enter the big mountains; I just hope you've taken on enough fluids and carbs,[1] as it'll be some time before we get any respite on some long descents in Parts Five and Six.

[1] Since this is software engineering, and not cycling, you probably want to steer clear of the carbs, which might make you sleepy, and instead get come coffee down you. You'll need all your attention in this part.

Much of C++ is about enforcing, manipulating, and converting type, and it can reasonably claim to be a strongly typed language. Alas, it's not perfect in this regard, and some of the most vexing problems one encounters in the language are about the ways in which the correct language interpretations are just a little bit different from what you know to be correct in a particular case.

Whenever one is trying to write generic code—whether template, or pre-processor customizable—one of the big bugbears is in the control of type, and the interconversion between types. The title of Part Four connotes the approach taken in most of the techniques described: that being a deliberate cognizance on the part of the programmer of what is going on and, often, an expression of that in the use of the techniques. In some cases this takes the form of using explicit constructs to manage or manipulate the conversions. In others, it simply entails giving a description of the issues, and providing recommendations as to the best approach(es) to take to avoid the potential pitfalls.

The four distinct concepts that we will examine in the first four chapters are Casts (Chapter 19), Shims (Chapter 20), Veneers (Chapter 21) and Bolt-Ins (Chapter 22), each addressing different aspects of type manipulation. Casts are used to change type or views of type. Shims aid in the (unambiguous) interpretation of type. Veneers allow layering of one type on another. Bolt-ins "bolt in" enhancing functionality over existing, and often complete, types. We will see that the notion of type conversion is not a simple one of just plain-old casts, but rather a rich continuum, exposing some powerful emergent properties.

The last chapter, Chapter 23, Template Constructors, describes a particularly vexing facet of C++'s template instantiation mechanism, encountered when deriving template classes and forwarding their constructor calls, as we do in Veneers and Bolt-ins.

Each chapter contains various examples of how these concepts can be put to use. Many of these examples highlight important fundamental techniques that underpin the later parts of the book, especially the use of Shims as a mechanism that underpins explicit generalization. Others are more esoteric, and perhaps less practically useful, but they are important as they demonstrate useful ways in which the language and compiler can be made to do what you require.



      Previous section   Next section