2

I recently reopened a visual studio project I last worked on a year ago, and I want to get it to compile under g++. Among other issues, the compiler complains about some template code that doesn't appear legal in the first place.

Specifically, some of the template class method's instantiate Iterators for their class that are defined lower down, with no forward declarations. This would not be a problem if I was not working with templates, because the class declarations themselves are perfectly legal; it's the method bodies, which would ordinarily be in source files, which are causing problems. It seems as though templates compile differently to account for this, at least under msvc.

Sample code:

template<class T>
class ClassA : public HasIterator<T>
{
public:
    Iterator<T> * GetIterator()
    {
        return new ClassAIterator<T>(this);
    }
};

template<class T>
class ClassAIterator : public Iterator<T>
{
    ClassA *foo;

public:
    AggregateWrapperIterator(ClassA *foo)
    {
        //...
    }

    bool HasNext()
    {
        //..
    }

    T Next()
    {
        //..
    }
};

I'd just add forward declarations but it get's complicated because of inheritance (there was a reason I set it up this way in the first place).

My question is this: for what reason does msvc allow this code, and does g++ have similar support?

user2345397
  • 301
  • 1
  • 11
  • 3
    MSVC lacks [two phase name lookup](https://stackoverflow.com/q/6273176/241631) for templates, so it doesn't catch a lot of errors in templates. AFAIK, there is no option in gcc to delay all name lookup until instantiation time. – Praetorian Jun 23 '15 at 00:49
  • Interesting. Is the standard method of dealing with this situation just to define the method outside the class at the end of the header? I suppose this would be nearly the same as having it defined in a source file. – user2345397 Jun 23 '15 at 02:31
  • Yes, an out of line definition within the header for `ClassA::GetIterator` after the definition of `ClassAIterator` seems like the right way to solve your problem. I must add that dynamically allocating a class named `ClassAIterator` makes me a bit wary of your design. – Praetorian Jun 23 '15 at 03:09
  • OT: you should return the iterator by value. This is not Java ;) – Daniel Jour Jun 23 '15 at 05:31
  • I'm confused; the return type is Iterator, which is an abstract class. Trying to return that by value wouldn't even compile. I think my example must be confusing. Or I'm not understanding you guys properly. – user2345397 Jun 23 '15 at 05:43

0 Answers0