Sunday, January 17, 2010

Back and forth on typedefs

A post about technical issues today.

I've been working with C++ and STL. While C++ is an old friend (dating back to 1997), STL is new to me. Yet it's not that big of a challenge. (Perhaps my experience with Perl and Ruby help me understand the goals of STL.)

One technique that I have been using is typedefs for STL types. STL has a syntax that leads to long type descriptions. For example, a simple list of strings might be:

std::vector<std::string>

and a hashmap with string keys and string values would be:

std::map<std::string, std::string>

Those are readable. Things get messy when the value for a hashmap is another type, such as a list of strings. Then you have:

std::map<std::string, std::vector<std::string>>

By itself, that's not bad. But you use this type in a number of constructs. It requires a lot of typing (or copying and pasting) and the elegant programmer in me winces at hard-coding the type throughout the program.  I fear a change in the data structure will require a lot of hunting for the references to the type, replacing the old type with the new.

The answer, in C++, is typedef. The typedef keyword lets you create your own tag for a type. So with

typedef std::mapstd::string, std::vector<std::string>> Map_Name_Entries;

You can create a simple-to-type name for your new type. In this case, "Map_Name_Entries". In addition to a shorter name, you get a descriptive name, one that can convey meaning to the programmer. (Me, or anyone else working on the code.)

At first, I was typedef-happy, using typedefs for all of my STL types.

Then I found that there were two classes of STL types. One class was generic, such as a list of strings. The other class was specific, with complex structures. The generic types had generic names; the complex types had specific names. In some cases, multiple complex types had the same structure but different names, since I used them in different contexts and for different purposes.

I changed my code and removed the typedefs. At first, I removed all of them. I found that using the raw STL syntax for the generic types made the code easier to understand. I also found that the raw STL for complex types was hard to understand.

So at this point, I have re-introduced the typedefs for complex types. My rules to divide simple and complex are unpublished and unvoiced. The decision to use the raw syntax or to use a typedef is more art than science, more emotional than rational. Yet they work, at least for me.


No comments:

Post a Comment