Tuesday, December 19, 2006

One word that matters

One word can change many things. And sometimes the words that one is not used to use so much might have a kind of magic in them.

Here is the problem we were facing yesterday. This piece of code was refusing to compile:

1    #include <vector>
2    template< class key , class hashImpl , class equalImpl >
3    class OMultiTypeInterfaceContainerHelperVar {
4        typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
5        InterfaceMap *m_pMap;
6        inline void * find() {
7            InterfaceMap::iterator iter;
8            return NULL;
9        }
10   };

The complain was about an expected ';' before 'iter' on line 7. One can conclude by looking close that the code is correct and start to file a bug in the gcc bugzilla :-) And yet, inspite of the fact that it looks very reasonable for anybody who has a basic knowledge of C++, this code is not valid C++ and the compiler is right. For the line 7 to compile correctly, InterfaceMap::iterator has to be a type. But the compiler cannot be 100% sure about this at the moment when it is compiling the template class. It will know more at the moment of the instantiation of the template, but not before. There is still a tiny little probability that there will be a specialization for a certain class key where the InterfaceMap::iterator will not be a type. Because the compiler is not 100% sure that the InterfaceMap::iterator is a type, it assumes that it is not.

But now what? How can one make the compiler accept the code? Simply, by telling it that the InterfaceMap::iterator is a type. Here it is where a word that is not so often used (In fact, your servant never had to use it for the while) becomes handy. If you precede the statement at the line 7 by the keyword typename, everything compiles without a quirk. The presence of this keyword takes the compiler out of the uncertainty and, with its mind settled, it accepts the code.

So, the rule of the thumb is to precede the use of the dependent nested types in templates always by the magic word typename.

Having said this, I am quite happy that the long winter evenings spent with Scott Meyers were not amiss.