alias to a property as an argument to a mixin template

monarch_dodra monarchdodra at gmail.com
Sun Sep 23 12:48:10 PDT 2012


On Sunday, 23 September 2012 at 18:48:14 UTC, comco wrote:
> For this program I'm getting an "Error: need 'this' to access 
> member x" at line (*). Does that mean that we cannot alias a 
> property as an argument of a template mixin?
>
>     import std.stdio;
>
>     mixin template T(alias a) {
>         void f() {
>             writeln(a); // (*)
>         }
>     }
>
>     struct S {
>         int x;
>     }
>
>     void main() {
>         auto s = S(4);
>         mixin T!(s.x);
>         f();
>     }
>
> If I change main() as follows, I still get the same error:
>
>     void main1() {
>         auto s = S(4);
>         with (s) {
>             mixin T!(x);
>             f();
>         }
>     }
>
> But now, I can get it working by this trick:
>
>     import std.stdio;
>
>     mixin template T(alias a) {
>         void f() {
>             mixin("writeln(" ~ a.stringof ~ ");");
>         }
>     }
>
>     struct S {
>         int x;
>     }
>
>     void main() {
>         auto s = S(4);
>         with (s) {
>             mixin T!(x);
>             f();
>         }
>     } // prints 4
>
> So, using string mixins works, but explicit alias to the 
> property name seems not to. Why is that and is there any other 
> way of achieving the result witout using template mixins?

I think it is normal behavior. Keep in mind what you are 
instantiating your template with (something know at compile 
time), and how you are using it.

When you write "T!(s.x)", the compiler understands it as "S.x" 
(in D, you may use an instance when you could use a type).

Of course, when trying to use the mixed-in in T, you get:

      void f() {
          writeln(S.x);
      }

To which the compiler replies: "Who's x?" (eg: I need "this"). 
EG: as the title implies, you parametrized your template on a 
property, but there is no associated instance.

What you are really trying to do, is parametrize your template on 
a variable *name*, so you were right taking your mixin approach. 
However, I think this is more like what you want:

--------
import std.stdio;

//ss is the variable name
mixin template T(alias ss) {
     void f() {
         mixin("writeln(" ~ ss ~ ");");
     }
}

struct S {
     int x;
}

void main() {
     auto s = S(4);
     mixin T!"s.x"; //mix with the variable "s.x"
     f();
}
--------


....


On a side note, if the alias was named "s", the compiler would 
have gotten confused, because of the conflict with the mixed'd in 
s. THAT however, I think is a bug.


More information about the Digitalmars-d-learn mailing list