views:

16

answers:

1

check this out:

template <class T>
class Test: public T
{
public:

    void TestFunc()
    {
        T::SubClass bob;
    }
};

this fails when compiling for iPhone (expected ';' before 'bob'). works on other platforms

this is a simplified example of what we are actually trying to do, which is inherit from an std::map<> and inside that class, create an iterator.

+3  A: 

Very often encountered issue. Put typename:

template <class T>
class Test: public T
{
public:

    void TestFunc()
    {
        typename T::SubClass bob;
    }
};

T::SubClass is a dependent name. While parsing the template, the compiler doesn't know yet whether it will be a type. For still being able to parse it (and collect information won thereby), it assumes it is not a type. But then, the line must be an expression, and misses an operator between the two names. typename will tell it the name is a type, and the line then becomes a declaration.


It may not be apparent why it fails above because the whole line cannot be an expression. But there are other situation where this isn't possible to decide on the form of the whole statement:

T::SubClass * bob;

Is that a multiplication, or a pointer declaration? The compiler will assume it is a multiplication. If later when instantiating the template it figures out that T::SubClass names a type, it will rise an error message. typename will also here tell the compiler to parse this as a declaration instead of an expression (by taking T::SubClass as a type).

Notice some compilers may still work without typename (if i remember right, the MSVC compiler is one of them). I think this should come with the restriction that those compilers won't do two-phase name lookup: They will parse the complete template at instantiation time, and all names, even those that were not visible in the definition of the template, will be found (as opposed to what the Standard says, that treats name lookup at definition/instantiation differently).

Visit the Template FAQ for further assistance: C++ Templates FAQ

Johannes Schaub - litb
lol, lame... thanks for that. fixed my problem by adding:typedef typename std::map<KEY,VALUE>::iterator iterator;to my class inheriting from std::map.
matt
cool, yeah, I can see how that might be a problem.when I actually Instantiated Test and called TestFunc on it, the Iphone compiler did come up with more errors and actually suggested I put typename in front of it!the biggest problem we've had with porting is that much of our templated stuff is actually never called, so other compilers are just completely brushing over them! not even picking up blatant syntax errors. I guess Unit Tests ftw...
matt