I’m porting over some templated code from Windows and I’m hitting some compiler differences on the iPhone 3.2 SDK.
Original code inside a class template’s member function is:
return BinarySearch<uint32, CSimpleKey<T> >(key);
where BinarySearch is a method inherited from another template.
This produces the following error:
csimplekeytable.h:131: error: no matching function for call to 'BinarySearch(NEngine::uint32&)'
The visual studio compiler seems to walk up the template hierarchy fine but gcc needs me to fully qualify where the function comes from (I have verified this by fixing the same issues with template member variables that way).
So I now need to change this into:
return CSimpleTable<CSimpleKey<T> >::BinarySearch<uint32, CSimpleKey<T> >(key);
Which now produces the following error:
csimplekeytable.h:132: error: expected primary-expression before ',' token
csimplekeytable.h:132: error: expected primary-expression before '>' token
After some head scratching, I believe what’s going on here is that it’s trying to resolve the ‘<‘ before BinarySearch as a ‘Less Than’ operator for some reason.
So two questions:
– Am I on the right path with my interpretation of the error?
– How do I fix it?
-D
If
CSimpleTableis the base class, you need to qualify your call with that base class name or alternatively withthis. But since both of these depend on the template parameters, the compiler cannot lookup what the nameBinarySearchmeans. It could be a static integer constant, which you compare against something else, or it could be a template that you put arguments enclosed in<...>for. You need to tell the compiler about the latterOr with
thisThe reason for the qualification is that the compiler does not look for unqualified names in base classes that depend on template parameters (in your case the parameter is
T), since the binding of the name would depend on whether the base class has such a name or not, which is considered unfortunate. For a plain name likeBinarySearch, there is in addition no indication that this name depends on a template parameter, thus the Standard requires compilers not to delay lookup of the name until instantiation. So the name, even if lookup in dependent bases would be allowed on instantiation (which isn’t), couldn’t be found anyway.You have to explicitly tell the compiler to look in the enclosing class by qualifying it, in which event the compiler will include dependent base classes during lookup when instantiating. Prefixing with
thisor the class name will also make the name dependent, thus delaying lookup of it until instantiation. These two facts are required for it to work.