How to compile this with g++ (compiles with Visual Studio)

closed account (1yR4jE8b)
I've been practicing polymorphism and using abstract classes lately by writing different implementations of simple data structures using abstract classes.
I've come across some strange compiler behavior and I'm not sure if I'm writing it wrong (and Visual Studio is offending the standard) or if it's a bug in G++.

The issue stems from the inheritance of typedefs inside template classes


ListInterface.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef _LIST_INTERFACE_H_
#define _LIST_INTERFACE_H_

template <class T>
class ListInterface
{
public:
    typedef unsigned int index_type;
    //abstract member functions
};

#endif /* _LIST_INTERFACE_H_*/ 



ArrayList.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* Include Guards and dependancy includes */

template <class T>
class ArrayList : public ListInterface<T>
{
public:
    static const index_type DEFAULT_CAPACITY;
    //rest of my class
};

template <class T>
const typename ArrayList<T>::index_type ArrayList<T>::DEFAULT_CAPACITY = 10;

//rest of definition 


While this compiles and runs just fine using Visual Studio 2008/2010, G++ gives a wall of errors (with only the first few dozen being related to the actual error) the rest just being compiler confusing I'm thinking.


In file included from main.cpp:3:
ArrayList.h:20: error: 'index_type' has not been declared
ArrayList.h:29: error: 'index_type' does not name a type
ArrayList.h:29: note: (perhaps 'typename ListInterface<T>::index_type' was inten
ded)
ArrayList.h:30: error: 'index_type' does not name a type
ArrayList.h:30: note: (perhaps 'typename ListInterface<T>::index_type' was inten
ded)
ArrayList.h:38: error: 'index_type' has not been declared
ArrayList.h:41: error: 'index_type' does not name a type
ArrayList.h:41: note: (perhaps 'typename ListInterface<T>::index_type' was inten
ded)
ArrayList.h:45: error: conflicting declaration 'const typename ArrayList<T>::ind
ex_type ArrayList<T>::DEFAULT_CAPACITY'
ArrayList.h:14: error: 'ArrayList<T>::DEFAULT_CAPACITY' has a previous declarati
on as 'const typename ListInterface<T>::index_type ArrayList<T>::DEFAULT_CAPACIT
Y'
ArrayList.h:45: error: declaration of 'const typename ListInterface<T>::index_ty
pe ArrayList<T>::DEFAULT_CAPACITY' outside of class is not definition


*add it just keeps on going, actually...*


From a quick google search it appears to have something to do with 'dependant names', but I have no idea on how to go about solving this compilation problem.
Last edited on
templates are weird with dependent / nondependent types. You really have to spell it out for the compiler.

index_type exists in ListInterface, not in ArrayList.

Here is what I did to get it compiling on GCC:

1
2
3
4
5
6
7
8
9
template <class T>
class ArrayList : public ListInterface<T>
{
public:
    static const typename ListInterface<T>::index_type DEFAULT_CAPACITY;  // note ListInterface:: and typename
};

template <class T>
const typename ListInterface<T>::index_type ArrayList<T>::DEFAULT_CAPACITY = 10; // ditto 


Alternatively you could typedef it in ArrayList again:

1
2
3
4
5
6
7
8
9
10
template <class T>
class ArrayList : public ListInterface<T>
{
public:
    typedef typename ListInterface<T>::index_type index_type; // retypedef
    static const index_type DEFAULT_CAPACITY;  // now this works
};

template <class T>
const typename ArrayList<T>::index_type ArrayList<T>::DEFAULT_CAPACITY = 10;  // still need the hints here though 
closed account (1yR4jE8b)
Retypedef'ing was the best solution in my case, otherwise I would have had to rename all my index_type variables to ListInterface<T>::index_type. Thanks a bunch.

Any idea why it compiles fine the way I had it with Visual Studio and had to explicitly typedef it again using g++? Is it simply Microsofts compiler is more advanced at resolving dependent names, or is it a standards vs language extensions deal between the two compilers, or is it just a flat out deficiency in g++?
I don't know enough about the standard in this area to say for sure.
Technically G++ is correct to the standard - typenames are not carried forward from base class to derived classes.
Microsoft is just allowing you to do the obvious (and is not in keeping with the standard)

[EDIT]
I should clarify that this is in regard to templates
Last edited on
Topic archived. No new replies allowed.