2015-03-06 3 views
2

Есть ли способ использовать имена функций mixin (или для любых имен членов), кроме строк mixin?Имена функций Mixin

В настоящее время я делаю это так:

mixin template PacketValue(T, string name, PacketMode mode, size_t offset) { 
    import std.string : format; 

    static if (mode == PacketMode.both || mode == PacketMode.write) { 
     enum writePacketFormat = "void %s(T value) { write!T(value, offset); }"; 
     mixin(format(writePacketFormat, name)); 
    } 

    static if (mode == PacketMode.both || mode == PacketMode.read) { 
     enum readPacketFormat = "auto %s() { return read!T(offset); }"; 
     mixin(format(readPacketFormat, name)); 
    } 
} 

И он используется отл. например:

class WritePacket : Packet!(PacketMode.write) { 
    public: 
     this(ushort size) { 
      super(cast(ushort)1001, cast(ushort)(4 + size)); 
     } 


    @property { 
     mixin PacketValue!(uint, "value1", PacketMode.write, 4); 
     mixin PacketValue!(uint, "value2", PacketMode.write, 8); 
     mixin PacketValue!(ushort, "value3", PacketMode.write, 12); 
    } 
} 

Если значениями «value1», «value2» и «value3» будут имена функций. В этом случае функции свойств.

Мне было просто интересно, есть ли лучший способ достичь этого или нет.

+0

Ответы на http://stackoverflow.com/questions/28814898/mixins-names-parameterization-with-template- аргумент может представлять интерес. – rcorre

+0

Нет, уже видел. Они полагаются на то же, что и я, используя строки. Это то, о чем я спрашивал, можно ли избежать. – Bauss

+1

Вторая часть этого ответа, используя псевдонимы для получения более приятного имени, я думаю, что лучше всего вы можете это сделать. –

ответ

0

Альтернативным подходом будет opDispatch с условием шаблона для имени.

mixin template PacketValue(T, string name, PacketMode mode, size_t offset) { 

static if (mode == PacketMode.both || mode == PacketMode.write) 
{ 
    void opDispatch(string op,T)(T value) if (op == name) 
    { 
     write!T(value, offset); 
    } 
} 

static if (mode == PacketMode.both || mode == PacketMode.read) 
{ 
    auto opDispatch(string op)() if (op == name) 
    { 
     return read!T(offset); 
    } 
} 

}

хотя вы, вероятно, оптимизировать его в один opDispatch

Смежные вопросы