[Question] About mixin, template and alias

monarch_dodra monarchdodra at gmail.com
Sun Sep 22 14:02:09 PDT 2013


On Sunday, 22 September 2013 at 18:31:20 UTC, Michael wrote:
> /////// fire.d
>
> import std.stdio;
>
> alias void delegate() EventHandler;
>
> class Event(T)
> {
>     private T[] _events;
>
>     public void opOpAssign(string op)(T param) if (op == "~")
>     {
>         writeln(param.funcptr);
>         _events ~= param;
>     }
>
>     public void opCall(ParamType ...)(ParamType params)
>     {
>         emit(params);
>     }
>
>     protected void emit(ParamType ...)(ParamType params)
>     {
>         foreach (event; _events)
>             event(params);
>     }
> }
>
> mixin template AddEvent(DelegateType, string member)
> {
>     auto eventObserver =  new Event!DelegateType();
>
>     mixin("alias eventObserver " ~ member ~ ";");
> }
>
> class Fire
> {
>     public mixin AddEvent!(EventHandler, "click");
> }
>
> /////// water.d
> import std.stdio;
>
> import fire;
>
> class Water : Fire
> {
>
> }
>
> void main()
> {
>     auto fire  = new Fire();
>     auto water = new Water();
>     water.click ~= () { writeln("Water!"); };
>     fire.click  ~= () { writeln("Fire!");  };
>
>     fire.click();
> }
>
>
> Output:
> Water!
> Fire!
>
> Someone can explain me a behaviour of above code? Why not 
> "Fire!" only?

This:
//----
     auto eventObserver =  new Event!DelegateType();
//----
Does not do what you think it does: It *statically* initializes 
"eventObserver" to the *single* "new Event!DelegateType();". SO 
basically, all your instances are sharing the same Event.

I'm surprised this compiles at all, what with Fire.init depending 
on a run-time call, but apparently, dmd is "smart enough" to do 
the allocation at compile time.


More information about the Digitalmars-d-learn mailing list