digitalmars.D.learn - friends with phobos, workaround?
- Daniel N (18/18) Sep 09 2015 For the record, I think D made the right decision... omitting
- Idan Arye (33/51) Sep 09 2015 How about using a mixin
- Daniel N (37/39) Sep 10 2015 Thanks, it's a good solution. My only reservation is I would
- Daniel N (2/31) Sep 10 2015 PS 'private:' should of course be 'public:' when using this idiom.
- Adam D. Ruppe (12/14) Sep 10 2015 That's disgustingly.... genius. I'm a bit jealous I didn't think
- Daniel N (9/17) Sep 11 2015 super():
- Adam D. Ruppe (4/6) Sep 10 2015 I actually think that should be a free function in the module
For the record, I think D made the right decision... omitting friends. However there's one case in particular which I find useful, anyone see a good workaround for this? #include <memory> class Friendly { private: int val; Friendly(int&& val) : val(val) {} friend std::unique_ptr<Friendly> std::make_unique<Friendly>(int&& val); }; int main() { auto yay = std::make_unique<Friendly>(1); auto nay = new Friendly(1); }
Sep 09 2015
On Wednesday, 9 September 2015 at 20:19:44 UTC, Daniel N wrote:For the record, I think D made the right decision... omitting friends. However there's one case in particular which I find useful, anyone see a good workaround for this? #include <memory> class Friendly { private: int val; Friendly(int&& val) : val(val) {} friend std::unique_ptr<Friendly> std::make_unique<Friendly>(int&& val); }; int main() { auto yay = std::make_unique<Friendly>(1); auto nay = new Friendly(1); }How about using a mixin template(http://dlang.org/template-mixin.html)? module makeunique; mixin template MakeUnique(Args...) { import std.typecons : Unique; static Unique!(typeof(this)) makeUnique(Args args) { return Unique!Friendly(new typeof(this)(args)); } } module friendly; import makeunique; struct Friendly { private: int val; this(int val) { this.val = val; } public: mixin MakeUnique!(int); }; module app; import std.stdio; import std.typecons; import friendly; void main() { auto yay = Friendly.makeUnique(1); }
Sep 09 2015
On Wednesday, 9 September 2015 at 23:44:14 UTC, Idan Arye wrote:How about using a mixin template(http://dlang.org/template-mixin.html)?Thanks, it's a good solution. My only reservation is I would prefer to find a way to directly invoke a symbol in std.* as otherwise different frameworks might invent their own conventions(well they might do that anyway). After a nights sleep, I actually found such a solution! This opens the door to a new class of meta-programming; introspect the caller! :) import std.typecons; class Awesome1 { private: int val; this(string caller = __MODULE__)(int val) if(caller == "std.conv") // Use scoped!Awesome { this.val = val; } } class Awesome2 { private: int val; this(string caller = __MODULE__)(int val) { static assert(caller == "std.conv", "Use scoped!Awesome(...)!"); this.val = val; } } void main() { static assert(__traits(compiles, scoped!Awesome1(1))); static assert(__traits(compiles, scoped!Awesome2(1))); static assert(!__traits(compiles, new Awesome1(1))); static assert(!__traits(compiles, new Awesome2(1))); }
Sep 10 2015
On Thursday, 10 September 2015 at 08:22:29 UTC, Daniel N wrote:import std.typecons; class Awesome1 { private: int val; this(string caller = __MODULE__)(int val) if(caller == "std.conv") // Use scoped!Awesome { this.val = val; } } class Awesome2 { private: int val; this(string caller = __MODULE__)(int val) { static assert(caller == "std.conv", "Use scoped!Awesome(...)!"); this.val = val; } } void main() { static assert(__traits(compiles, scoped!Awesome1(1))); static assert(__traits(compiles, scoped!Awesome2(1))); static assert(!__traits(compiles, new Awesome1(1))); static assert(!__traits(compiles, new Awesome2(1))); }PS 'private:' should of course be 'public:' when using this idiom.
Sep 10 2015
On Thursday, 10 September 2015 at 08:22:29 UTC, Daniel N wrote:this(string caller = __MODULE__)(int val) if(caller == "std.conv") // Use scoped!AwesomeThat's disgustingly.... genius. I'm a bit jealous I didn't think of it myself! One slight problem though: you couldn't call super() from a derived class, since the constructor wouldn't even exist due to the constraint. You could just put the hard work in a protected helper function though and then child classes call it instead of the super ctor.... then you could do a mixin template that forwards to that to kinda automate this ctor too. this is fairly usable!
Sep 10 2015
On Thursday, 10 September 2015 at 13:19:08 UTC, Adam D. Ruppe wrote:On Thursday, 10 September 2015 at 08:22:29 UTC, Daniel N wrote:super(): Hmm, yes that's a slight nuisance but manageable. Thanks, coming from you that means a lot. :) Hmm, maybe I'll wait a week or two before I share my next trick to give you ample time to think of it also, meanwhile I'll just scribble it down in the margin of my copy of "D Cookbook". ;) ... just hope I didn't jinx myself now ...this(string caller = __MODULE__)(int val) if(caller == "std.conv") // Use scoped!AwesomeThat's disgustingly.... genius. I'm a bit jealous I didn't think of it myself! One slight problem though: you couldn't call super() from a derived class, since the constructor wouldn't even exist due to the constraint.
Sep 11 2015
On Wednesday, 9 September 2015 at 23:44:14 UTC, Idan Arye wrote:public: mixin MakeUnique!(int);I actually think that should be a free function in the module because then it can be used by derived classes too without having to mix it in each of them as well.
Sep 10 2015