Topic
  • No replies
SystemAdmin
SystemAdmin
196 Posts

Pinned topic xlC++ having troubles with Typedef

‏2011-02-08T13:12:49Z |
Hi,

I'm porting some old code that was written before the 98 C++ standard to compile in v10 of xlC.

Most of the times it's just a matter of adding a "typename" here and there, changing scopes and such. However, I'm experiencing some hard trouble with the following issue.

I have a template list class with all the things you expect from a list, including iterators.

There is a typedef inside this class for a comparison function pointer, as below:

typedef int (*compare_t) (const T*, const void*);

Then, this class is derived into a SortList class, which defines a Sort method, as such:

void Sort (compare_t cmpf=(compare_t)_cmpobj);

_cmpobj is defined in the List class as:
static int _cmpobj( const T* x, const T* y);

When I try to compile a code that uses the SortList class, this is what I'm getting:

1540-0063 (S) The text "compare_t" is unexpected.

Really, I can't see anything wrong with the typedef, classes or method definitions. Does anyone has any idea on what's happening here?
Updated on 2011-02-09T20:18:37Z at 2011-02-09T20:18:37Z by SystemAdmin
  • camorton
    camorton
    10 Posts

    Re: xlC++ having troubles with Typedef

    ‏2011-02-09T14:02:21Z  
    I suspect you are having trouble accessing names from a template-dependent base class.

    If the base class is not dependent as in this example:

    
    template <
    
    class A> struct cont1 
    { 
    
    static 
    
    int _cmpobj( 
    
    const A* x, 
    
    const A* y); typedef 
    
    int (*compare_t) (
    
    const A*, 
    
    const void*); 
    };     template <
    
    class B> struct cont2 : 
    
    public cont1<int> 
    { 
    
    void Sort (compare_t cmpf=(compare_t)_cmpobj); 
    };   template struct cont2<int>;
    


    The code compiles clean

    However if you make the base class dependent on a template parameter as in this example:

    
    template <
    
    class A> struct cont1 
    { 
    
    static 
    
    int _cmpobj( 
    
    const A* x, 
    
    const A* y); typedef 
    
    int (*compare_t) (
    
    const A*, 
    
    const void*); 
    };     template <
    
    class B> struct cont2 : 
    
    public cont1<B> 
    { 
    
    void Sort (compare_t cmpf=(compare_t)_cmpobj); 
    };   template struct cont2<int>;
    


    
    
    "a.cpp", line 11.15: 1540-0063 (S) The text 
    "compare_t" is unexpected. 
    "a.cpp", line 14.17: 1540-0138 (S) The undefined template 
    "cont2" must not be explicitly instantiated.
    


    In order for name lookup to find names in a dependent base class, the names should be qualified. Here are 2 versions that compile clean:

    
    template <
    
    class A> struct cont1 
    { 
    
    static 
    
    int _cmpobj( 
    
    const A* x, 
    
    const A* y); typedef 
    
    int (*compare_t) (
    
    const A*, 
    
    const void*); 
    };     template <
    
    class B> struct cont2 : 
    
    public cont1<B> 
    { typedef typename cont1<B>::compare_t compare_t; 
    
    void Sort (compare_t cmpf=(compare_t)cont1<B>::_cmpobj); 
    };   template struct cont2<int>;
    


    OR
    
    template <
    
    class A> struct cont1 
    { 
    
    static 
    
    int _cmpobj( 
    
    const A* x, 
    
    const A* y); typedef 
    
    int (*compare_t) (
    
    const A*, 
    
    const void*); 
    };     template <
    
    class B> struct cont2 : 
    
    public cont1<B> 
    { 
    
    void Sort (typename cont1<B>::compare_t cmpf=(typename cont1<B>::compare_t)cont1<B>::_cmpobj); 
    };   template struct cont2<int>;
    
  • SystemAdmin
    SystemAdmin
    196 Posts

    Re: xlC++ having troubles with Typedef

    ‏2011-02-09T20:18:37Z  
    • camorton
    • ‏2011-02-09T14:02:21Z
    I suspect you are having trouble accessing names from a template-dependent base class.

    If the base class is not dependent as in this example:

    <pre class="jive-pre"> template < class A> struct cont1 { static int _cmpobj( const A* x, const A* y); typedef int (*compare_t) ( const A*, const void*); }; template < class B> struct cont2 : public cont1<int> { void Sort (compare_t cmpf=(compare_t)_cmpobj); }; template struct cont2<int>; </pre>

    The code compiles clean

    However if you make the base class dependent on a template parameter as in this example:

    <pre class="jive-pre"> template < class A> struct cont1 { static int _cmpobj( const A* x, const A* y); typedef int (*compare_t) ( const A*, const void*); }; template < class B> struct cont2 : public cont1<B> { void Sort (compare_t cmpf=(compare_t)_cmpobj); }; template struct cont2<int>; </pre>

    <pre class="jive-pre"> "a.cpp", line 11.15: 1540-0063 (S) The text "compare_t" is unexpected. "a.cpp", line 14.17: 1540-0138 (S) The undefined template "cont2" must not be explicitly instantiated. </pre>

    In order for name lookup to find names in a dependent base class, the names should be qualified. Here are 2 versions that compile clean:

    <pre class="jive-pre"> template < class A> struct cont1 { static int _cmpobj( const A* x, const A* y); typedef int (*compare_t) ( const A*, const void*); }; template < class B> struct cont2 : public cont1<B> { typedef typename cont1<B>::compare_t compare_t; void Sort (compare_t cmpf=(compare_t)cont1<B>::_cmpobj); }; template struct cont2<int>; </pre>

    OR
    <pre class="jive-pre"> template < class A> struct cont1 { static int _cmpobj( const A* x, const A* y); typedef int (*compare_t) ( const A*, const void*); }; template < class B> struct cont2 : public cont1<B> { void Sort (typename cont1<B>::compare_t cmpf=(typename cont1<B>::compare_t)cont1<B>::_cmpobj); }; template struct cont2<int>; </pre>
    Thank you, this worked really great!