On Tue, Apr 24, 2012 at 08:03:07PM +0200, Timon Gehr wrote: > On 04/24/2012 07:37 PM, H. S. Teoh wrote: > >I'm trying to write a template function for doing member-wise > >comparisons between two objects, with an optional list of members to > >ignore. But I can't seem to figure out the syntax for passing a list of > >strings (or an AA of strings) to the function? > > > >I tried this: > > > > bool compareByMemb(string[] ignores, T)(T obj1, T obj2) { > > foreach (name; __traits(getAllMembers, T)) { > > ... > > } > > } > > > >but the compiler complains: > > > > Error: arithmetic/string type expected for value-parameter, not string[] [...] > Try using an alias parameter (with an optional type constraint). imo > the template instantiation semantics needs a clean-up.
Thanks, that did it! For posterity, here's the code (which I think is generally usable for many more things than I'm using it for in my code): bool membCmp(T)(T t1, T t2) { return membCmpIgnoring!(cast(string[])[])(t1, t2); } bool membCmpIgnoring(alias ignores, T)(T t1, T t2) if (is(typeof(ignores)==string[])) { nextMemb: foreach (name; __traits(allMembers, T)) { foreach (i; ignores) { if (name == i) continue nextMemb; } static if (__traits(compiles, &__traits(getMember, t1, name))) { alias typeof(__traits(getMember, t1, name)) type; static if (!is(type==function)) { auto val1 = __traits(getMember, t1, name); auto val2 = __traits(getMember, t2, name); if (val1 != val2) return false; } } } return true; } Given two structs or objects, X and Y, this lets you do an easy implementation of opEquals(): bool opEquals(Object obj) { auto o = cast(typeof(this))obj; return obj && membCmp(this, o); } If you wish to ignore some fields, say x and y, in the comparison, then just do this: bool opEquals(Object obj) { auto o = cast(typeof(this))obj; return obj && membCmpIgnoring!(["x", "y"])(this, o); } Question: is it possible to sugar up the syntax even more, by allowing an array of aliases? Or is that pushing the template syntax a bit too far? I.e., can we make it possible to write: membCmpIgnoring!(x,y)(this, o) without the string list syntax? T -- Prosperity breeds contempt, and poverty breeds consent. -- Suck.com