Nested Class reference problem


#1

I have two classes, each with a listener class. I’d like for each of these classes to listen to the other but I get an error trying to forward declare them.

class B
class B::Listener <-- This the compiler does not like, since B is not complete at this point

class A : public B::Listener
{
public:
class Listener {}
}

class B : public A::Listener
{
public:
class Listener{}
}

The compiler complains about the ‘class B::Listener’ forward reference.

Any suggestions?


#2

Hi babazaroni, I’m afraid you cannot write your code that way. There’re two little issues here:
(1) C++ doesn’t allow to forward declare class details, which is why the compiler complains in line 2 (Listener is a detail of class B)
(2) even if C++ allowed this, you cannot inherit or instantiate a forward declared class, which is the core problem here: basically your code says A requires B and B requires A, a cyclic dependency that cannot be resolved in general

I don’t know your exact use case, but you may want to fix the general issue with something like this:

// declare A and B
class A;
class B;

class ListenerA {
    // can be defined here
    void funcThatRequiresDeclarationOfA() {}

    // declare here, define later
    void funcThatRequiresDefinitionOfA();
}

class ListenerB {
    // same story as ListenerA
    // may be a nested class, but consider symmetry
}

class A : public ListenerB {
}

class B : public ListenerA {
}

void ListenerA::funcThatRequiresDefinitionOfA() {
    // implement after class details of A were defined
}

#3

Doesn’t C++14 or 17 add support for predeclaring inner classes…? I vaguely remember hearing that, but could be mistaken…


#4

Wouldn’t help much here as class A and B derive from Listener::B and Listener::A. At this point the compiler needs to have the definition.


#5

Yes: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0289r0.pdf but won’t it make it to C++17 unfortunately. It would fix (1), but as also Fabian mentioned (2) is another issue.