How do I avoid a nonstatic reference error

The following code:
1
2
3
4
5
6
7
8
9
10
class X {
public:
   const X& x;
   class Y {
      void func() { x.run(); }
   }; // class Y
   void run() {};
   X() : x(*this) {}
}; // class X

Has the following error message in MSVS:
E0245 a nonstatic member reference must be relative to a specific object
for x.run() above.

I think I understand the message but I don't know how to get around it. 'x' is a reference and x.run() should be able to reference run() in class X. How do I get around this? I can't create a new instance of class X?
Last edited on
class Y does not contain a member called 'x'. What exactly are you trying to do? What is the purpose of the Y class? Why does the X class need to contain a reference to itself?

It's hard to know what you want, because the example looks completely contrived to me.
Maybe you can tell us what design you're trying to implement from a higher level, and we can try to help guide you.

Edit: Something like this will compile, but I still don't know if it's what you're looking for.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Example program
#include <iostream>

class X {
public:

   class Y {
   public:
      const X& x;
      Y(const X& x) : x(x) { }
      
      void func() { x.run(); }
   };
   
   Y y;

   X() : y(*this) { }

   
   void run() const { std::cout << "run!\n"; };

};


int main()
{
    X x;
    x.y.func();
}
Last edited on
you should be able to create an object in your main to call said function, that's the point of passing by reference. You reference one variable to the specific one in the class / struct.
@Ganado x is not a member of class Y. x is a member of class X and has public visibility. I would like to call run(), a method in X, from Y. You have mentioned one way of doing this. Passing a reference to an X object to Y through its constructor, Y(X& x): x(x) {}. Frankly in my haste to draw a wrong conclusion that one just skipped by me. And in thinking about it I guess this is the only way.

If I make Y private, thereby not allowing a Y object to be instantiated outside of X, does this change the equation so the x.run() can be used? In this case, Y can only be instantiated if X is instantiated. No X, no Y.
If I make Y private, thereby not allowing a Y object to be instantiated outside of X, does this change the equation so the x.run() can be used?
Public/private and the ability to call x.run() from within the Y class are two orthogonal issues here. The problem is that in your original code, x.run() cannot be called because x is not part of the Y class.

If you made x be static, you could call it, but then you would only have one global instance of that x variable, like a singleton. Seems like an overly complicated design.
Last edited on
@Ganado Ahem (also, "Aho") you're right. What I eventually did is to riff off of you and just pass a damn'd X pointer into Y, and use this pointer to execute X->run(). Worked.

What I have in my unalterable wisdom (means "I'm stubborn") done, is to create a Gawk-like I/O interface. This means that the entire application is I/O driven, not process driven, and the I/O layer makes direct calls to callback functions, BEGIN, BEGINFILE, ENDFILE, PROCESS, and END.

At the application side there are two separate conditions, call them A and B. Now the A condition is satisfied for the first input 'file', and the B condition is satisfied for the remaining files. There are about 2,900 input lines total of which about 147 are part of A processing. Initially I had a flag to distinguish the two cases. Then, I thought, why don't I remove the conditional and pass different instances of the callback functions to (my) Gawk. That way the Gawk processing remains unaltered and A logic ENDFILE can make the switch. Bizarre. Unconventional. But it's pretty and it works.

And that, dear friends, is how the World Ends (not with a bang but in loud laughter).
thanks
Topic archived. No new replies allowed.