Re: Define methods using templates
I just saw this post, which is essentially the same question as Basile Burg's. I hope that a college (in France?) is teaching D and that this is a homework assignment. Cool stuff! :) Maybe using templates to create properties is a bit overkill in this example. But I could not solve what I thought would be a very simple and straightforward template use-case (initially I'm an embedded RT system C/asm developer). I'm doing this for a personal project of a 3D engine. As I know little about C++/Java or other OO language, I thought I would do it directly in D, which seems very promising to me (but unfortunately not taught in France as far as I know).
Re: Define methods using templates
On 12/30/14 8:17 AM, Claude wrote: Hello, I'm trying to use templates to define several methods (property setters) within a class to avoid some code duplication. Here is an attempt: class Camera { private: Vector4 m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: void SetProperty(Tin, alias Field)(ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); alias pos = SetProperty!(Vector4, m_pos); alias ratio = SetProperty!(float, m_ratio); alias near = SetProperty!(float, m_near); alias far = SetProperty!(float, m_far); } I get this kind of compilation error: Error: template instance SetProperty!(float[], m_pos) cannot use local 'm_pos' as parameter to non-global template SetProperty(Tin, alias Field)(ref Tin param) I don't understand why that error occurs. I think it has to do with the fact that when you are defining the aliases, m_pos for example, is an *instance* member so requires an instance to get an alias. What you are probably better off doing is: void SetProperty(Tin, string Field)(ref Tin param) @property pure @safe { mixin(Field ~ = param;); m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); I would also put some strict template constraints on the Field string too, because one abuse SetProperty pretty easily there. -Steve
Re: Define methods using templates
On 12/30/14 8:48 AM, Steven Schveighoffer wrote: I think it has to do with the fact that when you are defining the aliases, m_pos for example, is an *instance* member so requires an instance to get an alias. What you are probably better off doing is: void SetProperty(Tin, string Field)(ref Tin param) @property pure @safe { mixin(Field ~ = param;); m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); I would also put some strict template constraints on the Field string too, because one abuse SetProperty pretty easily there. A possibly more elegant solution, use opDispatch: void opDispatch(string Field, Tin)(ref Tin param) @property pure @safe if(Field == pos || Field == ratio || ...) { mixin(m_ ~ Field ~ = param;); m_matrixCalculated = false; } Not sure if opDispatch works as a @property this way... -Steve
Re: Define methods using templates
V Tue, 30 Dec 2014 13:17:08 + Claude via Digitalmars-d-learn digitalmars-d-learn@puremagic.com napsáno: Hello, I'm trying to use templates to define several methods (property setters) within a class to avoid some code duplication. Here is an attempt: class Camera { private: Vector4 m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: void SetProperty(Tin, alias Field)(ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } alias pos = SetProperty!(float[], m_pos); alias pos = SetProperty!(Vector4, m_pos); alias ratio = SetProperty!(float, m_ratio); alias near = SetProperty!(float, m_near); alias far = SetProperty!(float, m_far); } I get this kind of compilation error: Error: template instance SetProperty!(float[], m_pos) cannot use local 'm_pos' as parameter to non-global template SetProperty(Tin, alias Field)(ref Tin param) I don't understand why that error occurs. And I cannot find any elegant solutions (even with mixin's) to declare a template and then instantiate it in a single line to define the methods I want. Does any of you have an idea? Thanks class Camera { private: int m_pos; float m_fov, m_ratio, m_near, m_far; bool m_matrixCalculated; public: mixin template opAssign(alias Field) { void opAssign(Tin)(auto ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } } mixin opAssign!(m_pos) pos; mixin opAssign!(m_fov) fov; mixin opAssign!(m_ratio) ratio; mixin opAssign!(m_near) near; mixin opAssign!(m_far) far; } void main() { Camera cam = new Camera(); cam.fov = 1.0; stdin.readln; }
Re: Define methods using templates
Thanks Steven and Daniel for your explanations. mixin template opAssign(alias Field) { void opAssign(Tin)(auto ref Tin param) @property pure @safe { Field = param; m_matrixCalculated = false; } } mixin opAssign!(m_pos) pos; I tested both the string mixin and opAssign implementations, and they work like a charm. I would have never thought of using both @property and opAssign, but it looks like a secure way of doing it for the compilation fails nicely if I type a wrong field in. src/camera.d(58): Error: undefined identifier m_os, did you mean variable m_pos?
Re: Define methods using templates
On 12/30/2014 05:17 AM, Claude wrote: use templates to define several methods (property setters) within a class to avoid some code duplication. I just saw this post, which is essentially the same question as Basile Burg's. I hope that a college (in France?) is teaching D and that this is a homework assignment. Cool stuff! :) Ali