September 30, 2014
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
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
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
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
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
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
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
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
Thanks!

Ali Çehreli, could you add this mention and possible the example to your book?
November 10, 2014
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

1 2
Next ›   Last »