leiiv
leiiv

Reputation: 875

Invalid use of incomplete type on g++

I have two classes that depend on each other:

class Foo; //forward declaration

template <typename T>
class Bar {
  public:
    Foo* foo_ptr;
    void DoSomething() {
      foo_ptr->DoSomething();
    }
};

class Foo {
  public:
    Bar<Foo>* bar_ptr;
    void DoSomething() {
      bar_ptr->DoSomething();
    }
};

When I compile it in g++, it was giving error of "Invalid use of incomplete type", but it was compiled nicely in MSVC 10. Is it possible to solve this problem while keeping the declaration and definition in one header file? (no cpp files) If this is not allowed in the standard, so is this one of the MSVC "bug" or "feature"?

Upvotes: 9

Views: 10238

Answers (3)

Keinstein
Keinstein

Reputation: 357

It works when you replace Foo* foo_ptr; by the template parameter T so that you get T* foo_ptr;. In this foo_ptr does not necessarily have to be a pointer or be predefined.

template <typename T>
class Bar {
  public:
    T foo;
    void DoSomething() {
      foo.DoSomething();
    }
};

class Foo {
  public:
    Bar<Foo>* bar_ptr;
    void DoSomething() {
      bar_ptr->DoSomething();
    }
};

Upvotes: 0

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76531

Yes, just move the method definitions out of the class definition:

class Foo; //forward declaration

template <typename T>
class Bar {
  public:
    Foo* foo_ptr;
    void DoSomething();
};

class Foo {
  public:
    Bar<Foo>* bar_ptr;
    void DoSomething() {
      bar_ptr->DoSomething();
    }
};

// Don't forget to make the function inline or you'll end up
// with multiple definitions
template <typename T>
inline void Bar<T>::DoSomething() {
  foo_ptr->DoSomething();
}

Upvotes: 9

Nathan Osman
Nathan Osman

Reputation: 73155

See this page: What is the best way to deal with co-dependent classes in C++?

It should clear up the problem and provides a couple nice solutions.

Upvotes: -1

Related Questions