Error: 'this' is only defined in non-static member functions, not parse

Timon Gehr timon.gehr at gmx.ch
Tue Jan 17 09:29:04 PST 2012


On 01/17/2012 06:02 PM, Matej Nanut wrote:
> On 17 January 2012 16:54, H. S. Teoh<hsteoh at quickfur.ath.cx>  wrote:
>> This may be the cause of your trouble. If the nested class references
>> members in the outer class, then moving it outside will break it, since
>> it won't have an outer scope anymore.
>>
>>
>> T
>>
>> --
>> Only boring people get bored. -- JM
>
> That was my guess too — but I'm not referencing the outer class. The
> outer class is just using instances of the inner one. Also, the line number
> of the error points to ‘new’ statements in the static method. (The calls
> which instantiate subclasses of the inner class.) If I do "return null" it
> works as well, without complaining. So it's not a referencing issue I think.
>
> As you all seem eager to help, I will copy the entire class, without
> subclasses, to here. I will be grateful for any comments regarding the
> current issue at hand or about the code in general.
>
> The ‘new’-ed Nodes are defined like ‘class CostNode : Node { ... }’.
>
> Another note, the outer class is an inner class of another class as well,
> if that makes a difference. Also, the outer class isn't really a class, it's
> a struct, but renaming that to ‘class’ doesn't change anything either.
>
> ---- code begin ----
>          class Node
>          {
>              static Node parse(ref string line)
>              {
>                  string mnemonic = munch(line, "A-Z");
>                  line = line.stripLeft();
>                  auto op = mnemonic in mnemonics;
>                  if (!op)
>                      throw new Exception("Unknown mnemonic: `" ~ mnemonic ~"'");
>
>                  final switch (*op)
>                  {
>                  case NodeType.COST:
>                      return new CostNode(line);
>                  case NodeType.PAUSE:
>                      return new PauseNode(line);
>                  case NodeType.COLDR:
>                      return new ColDrNode(line);
>                  case NodeType.COLRA:
>                      return new ColRaNode(line);
>                  case NodeType.DROP:
>                      return new DropNode(line);
>                  case NodeType.RAISE:
>                      return new RaiseNode(line);
>                  }
>
>                  /* Doing something like `return new Node()' doesn't work either.
>                   * Only `return null' works here. */
>              }
>
>              enum NodeType : ubyte
>              {
>                  COST,
>                  PAUSE,
>                  COLDR,
>                  COLRA,
>                  DROP,
>                  RAISE
>              }
>
>              static immutable NodeType[string] mnemonics;
>              static this()
>              {
>                  mnemonics = [
>                      "COST"  : NodeType.COST,
>                      "PAUSE" : NodeType.PAUSE,
>                      "COLDR" : NodeType.COLDR,
>                      "COLRA" : NodeType.COLRA,
>                      "DROP"  : NodeType.DROP,
>                      "RAISE" : NodeType.RAISE
>                  ];
>              }
>          }
>
> ---- code end ----

I'm quite sure that the error in your code occurs for the same reason as 
in the following code snippet:

class C{
     class D{}
     static make(){return new D();} // error
}

You can fix it by making D static:

class C{
     static class D{}
     static make(){return new D();} // ok
}

The reason is that non-static inner classes have an implicit 'outer' 
property that links to the class it was created with. Therefore, to 
construct them inside a member function, the implicit 'this' pointer is 
needed. If the 'outer' property is actually unwanted, it is best to 
declare inner classes as static.


More information about the Digitalmars-d-learn mailing list