digitalmars.D.learn - Strange behavior with opAssign and static if
- Andre (45/45) Feb 08 2014 Hi,
- Stanislav Blinov (17/17) Feb 08 2014 __traits(allMembers) gives you *all* members, including methods
- Andre (3/20) Feb 08 2014 Thanks a lot!
Hi, I have a template structure Decimal which is used in a OrderDb structure. The opAssign method in Decimal leads to strange behavior in the function execute(); The function execute stores the values of OrderDb in a variant array. Decimals value should be stored as strings. There is a static if for this condition. There is a compilation error for the line arr[i] = __traits(getMember, struc, member); -> function.main.OrderDb.opAssign (OrderDb p) is not callable using argument types () This compilation error disappears if I remove the opAssign method in Decimal. How can the opAssign of Decimal influence the code path for a non decimal field? Kind regards André ---code--- import std.traits: isInstanceOf; import std.variant; struct Decimal(int precision, int scale){ void opAssign(T)(T d) if (isInstanceOf!(Decimal, T)){} string toString(){return "10.22";}; } struct OrderDb{ string orderId; Decimal!(10,2) amount; } void main(){ execute(OrderDb()); } void execute(T)(T struc){ Variant[] arr = new Variant[](2); foreach (i, member;__traits(allMembers, T)){ static if (isInstanceOf!(Decimal, typeof(__traits(getMember, struc, member)))){ // Store decimals as string arr[i] = (__traits(getMember, struc, member)).toString(); } else { // Store other values with their types arr[i] = __traits(getMember, struc, member); } } }
Feb 08 2014
__traits(allMembers) gives you *all* members, including methods (even implicit). As soon as you define opAssign for your Decimal, it gets defined for OrderDb too, and then you try to assign to it :) What you need is something like this: void execute(T)(T struc){ Variant[] arr = new Variant[](2); foreach(i, member; struc.tupleof) { static if (isInstanceOf!(Decimal, typeof(member))){ // Store decimals as string arr[i] = member.toString(); } else { // Store other values with their types arr[i] = member; } } }
Feb 08 2014
Thanks a lot! This works great. Am 08.02.2014 14:27, schrieb Stanislav Blinov:__traits(allMembers) gives you *all* members, including methods (even implicit). As soon as you define opAssign for your Decimal, it gets defined for OrderDb too, and then you try to assign to it :) What you need is something like this: void execute(T)(T struc){ Variant[] arr = new Variant[](2); foreach(i, member; struc.tupleof) { static if (isInstanceOf!(Decimal, typeof(member))){ // Store decimals as string arr[i] = member.toString(); } else { // Store other values with their types arr[i] = member; } } }
Feb 08 2014