September 30, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay | On Sunday, 28 September 2014 at 20:28:11 UTC, Jay wrote:
> fwiw here's what i wrote:
>
> template New(T) if (is(T == class)) {
> T New(Args...) (Args args) {
> return new T(args);
> }
> }
My try
template New(T) if (is(T == class))
{
T New(Args...) (Args args) {
return new T(args);
}
}
unittest
{
class C { int x, y; }
auto x = New!C;
}
fails as
typecons_ex.d(60,16): Error: outer function context of typecons_ex.__unittestL64_4 is needed to 'new' nested class typecons_ex.__unittestL64_4.C
typecons_ex.d(67,14): Error: template instance typecons_ex.New!(C).New!() error instantiating
|
September 30, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On 09/30/2014 10:35 AM, "Nordlöw" wrote: > On Sunday, 28 September 2014 at 20:28:11 UTC, Jay wrote: >> fwiw here's what i wrote: >> >> template New(T) if (is(T == class)) { >> T New(Args...) (Args args) { >> return new T(args); >> } >> } > > My try > > template New(T) if (is(T == class)) > { > T New(Args...) (Args args) { > return new T(args); > } > } > > unittest > { > class C { int x, y; } > auto x = New!C; > } > > fails as > > typecons_ex.d(60,16): Error: outer function context of > typecons_ex.__unittestL64_4 is needed to 'new' nested class > typecons_ex.__unittestL64_4.C > typecons_ex.d(67,14): Error: template instance > typecons_ex.New!(C).New!() error instantiating Apparently, a class definition even inside a unittest blocks are considered to be nested classes. Normally, objects of nested classes are created by the 'this.new' syntax, 'this' meaning the object that wraps the nested class. class Outer { class Inner {} Inner makeInner() { return this.new Inner(); } } void main() { Outer o = new Outer; Outer.Inner i = o.makeInner(); } i contains a context pointer to its creators so that it can access the outer object's members. To make a nested class unnested, declare it as static, which seems to work in your case as well: class C { int x, y; } auto x = New!C(); Ali |
September 30, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 09/30/2014 11:07 AM, Ali Çehreli wrote: > To make a nested class unnested, declare it as static, which seems to > work in your case as well: > > class C { int x, y; } > auto x = New!C(); Copy+paste cannot read my mind. :( Of course there should be 'static' keyword there. :p static class C { int x, y; } Ali P.S. Shame! There is no mention of nested classes in my book. I put it in my short to-do list. |
September 30, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 9/30/14 2:07 PM, Ali Çehreli wrote:
>
> Apparently, a class definition even inside a unittest blocks are
> considered to be nested classes.
>
> Normally, objects of nested classes are created by the 'this.new'
> syntax, 'this' meaning the object that wraps the nested class.
I think unit test blocks are actually functions disguised as attributes.
So it makes sense.
void foo()
{
class C {}
auto c = New!C; // same error
}
-Steve
|
November 10, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | I can't understand how to use UFCS with instance of class: void main() { string name = "Suliman"; userName username = new userName(name); /// How to use UFCS here? userName.name.sayHello(); /// } class userName { string name; this(string name) { this.name = name; } void sayHello(string name) { writeln(name); } } |
November 10, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman Attachments: | On Mon, 10 Nov 2014 19:07:38 +0000 Suliman via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > /// How to use UFCS here? > userName.name.sayHello(); > /// you can't. a little explanation: UFCS substitutes only the first argument. and for class methods first argument is hidden 'this'. so you can't do it in this way, you have to write `userName.sayHello(name);` here. on the very low level calling class methods looks like this: // what you see: myobj.method(arg); // what compiler does: // method(myobj, arg); so in your example compiler sees this: sayHello(userName.name); which is obviously not what you want, 'cause you need this: sayHello(userName, name); or, taking it the easier way: UFCS is for *functions*, not for *methods*. that's why it "uniform *function* call syntax". it's not expected to work with methods, as the name suggests. maybe it will be easier to remember this way, rather than diving into compiler code transformations. ;-) |
November 10, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | On Mon, 10 Nov 2014 19:07:38 +0000, Suliman wrote:
> I can't understand how to use UFCS with instance of class:
>
> void main()
> {
>
> string name = "Suliman";
> userName username = new userName(name);
>
> /// How to use UFCS here?
> userName.name.sayHello();
> ///
> }
>
> class userName {
> string name;
>
> this(string name)
> {
> this.name = name;
> }
>
> void sayHello(string name)
> {
> writeln(name);
> }
> }
This has nothing to do with new--you're trying to use a virtual function
scoped
to class userName with a string. Rewrite it to a static module-scoped
function:
class userName {
string name;
this(string name)
{
this.name = name;
}
}
void sayHello(string name)
{
writeln(name);
}
void main()
{
string name = "Suliman";
userName username = new userName(name);
userName.name.sayHello();
}
|
November 10, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | On 11/10/2014 11:07 AM, Suliman wrote:
> I can't understand how to use UFCS with instance of class:
>
> void main()
> {
>
> string name = "Suliman";
> userName username = new userName(name);
>
> /// How to use UFCS here?
> userName.name.sayHello();
> ///
> }
>
> class userName
> {
> string name;
>
> this(string name)
> {
> this.name = name;
> }
>
> void sayHello(string name)
> {
> writeln(name);
> }
> }
UFCS is about calling a free-standing function like a member function. The following example makes more sense to me:
void main()
{
string name = "Suliman";
userName username = new userName(name);
username.sayHello(); // UFCS
}
// Does not have a sayHello() member function
class userName
{
string name;
this(string name)
{
this.name = name;
}
}
void sayHello(userName u)
{
import std.stdio;
writeln(u.name);
}
Ali
|
November 10, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Thanks! Ali Çehreli, could you add this mention and possible the example to your book? |
November 10, 2014 Re: is there any reason UFCS can't be used with 'new'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suliman | On 11/10/2014 12:04 PM, Suliman wrote: > Thanks! > > Ali Çehreli, could you add this mention and possible the example to your > book? Of course. Perhaps I should rephrase some of the descriptions here? http://ddili.org/ders/d.en/ufcs.html Please email me at acehreli@yahoo.com if you have specific suggestions. Thank you, Ali |
Copyright © 1999-2021 by the D Language Foundation