digitalmars.D.learn - inout, delegates, and visitor functions.
- Sebastien Alaiwan (33/33) Oct 24 2015 Hi all,
- ponce (10/43) Oct 24 2015 Hi Sebastien,
- Sebastien Alaiwan (36/36) Oct 24 2015 Hi ponce,
- ponce (4/36) Oct 24 2015 Clever. It works because of const inference on template functions.
Hi all, I'm trying to get the following code to work. (This code is a simplified version of some algebraic type). Is it possible to only declare one version of the 'apply' function? Or should I declare the const version and the non-const version? I tried using "inout", but I got the following error: test.d(28): Error: inout method test.E.apply is not callable using a mutable object class E { void apply(void delegate(inout(E) e) f) inout { f(this); } int val; } void m() { void setToZero(E e) { e.val = 0; } void printValue(const E e) { import std.stdio; writefln("Value: %s", e.val); } E obj; obj.apply(&setToZero); obj.apply(&printValue); } Thanks!
Oct 24 2015
On Saturday, 24 October 2015 at 08:51:58 UTC, Sebastien Alaiwan wrote:Hi all, I'm trying to get the following code to work. (This code is a simplified version of some algebraic type). Is it possible to only declare one version of the 'apply' function? Or should I declare the const version and the non-const version? I tried using "inout", but I got the following error: test.d(28): Error: inout method test.E.apply is not callable using a mutable object class E { void apply(void delegate(inout(E) e) f) inout { f(this); } int val; } void m() { void setToZero(E e) { e.val = 0; } void printValue(const E e) { import std.stdio; writefln("Value: %s", e.val); } E obj; obj.apply(&setToZero); obj.apply(&printValue); } Thanks!Hi Sebastien, That was an interesting question and I didn't succeed with 'inout' either without duplicating apply. I have a partial solution here: http://dpaste.dzfl.pl/b5ec7f16b912 which templatizes the delegate type, but is probably not what you want. The qualifier is not carried on to the apply() function. When taking a const delegate it will still not be const.
Oct 24 2015
Hi ponce, Thanks for your suggestion. I think I may have found the beginning of a solution: class E { import std.traits; void apply(this F, U)(void delegate(U e) f) if(is(Unqual!U == E)) { f(this); } int val; } int main() { void setToZero(E e) { e.val = 0; } void printValue(const E e) { import std.stdio; writefln("Value: %s", e.val); } E obj; obj.apply(&setToZero); obj.apply(&printValue); const(E) objConst; //objConst.apply(&setToZero); objConst.apply(&printValue); return 0; } Basically, I avoid the 'const'/'inout' attribute of the 'apply' function by using a 'this F' template argument. Then, I need a second template argument 'U', otherwise, I can't call 'printValue' on a non-const E instance.
Oct 24 2015
On Saturday, 24 October 2015 at 11:28:17 UTC, Sebastien Alaiwan wrote:Hi ponce, Thanks for your suggestion. I think I may have found the beginning of a solution: class E { import std.traits; void apply(this F, U)(void delegate(U e) f) if(is(Unqual!U == E)) { f(this); } int val; } int main() { void setToZero(E e) { e.val = 0; } void printValue(const E e) { import std.stdio; writefln("Value: %s", e.val); } E obj; obj.apply(&setToZero); obj.apply(&printValue); const(E) objConst; //objConst.apply(&setToZero); objConst.apply(&printValue); return 0; }Clever. It works because of const inference on template functions. Didn't know you could use 'this' as a type.
Oct 24 2015