Thread overview
Problem with immutables and Template typeof(this)
Dec 28, 2014
AuoroP
Dec 28, 2014
Tobias Pankrath
Dec 28, 2014
Tobias Pankrath
Dec 28, 2014
anonymous
Dec 29, 2014
AuoroP
Dec 29, 2014
AuoroP
Dec 30, 2014
Ali Çehreli
December 28, 2014
I have been trying to figure templates out...

template ExampleTemplate(T)
{
    struct ExampleTemplate
    {
        T value;

        // constructor
        auto this(T value)
        {
            this.value = value;
            return this;
        }

        // opAdd
        typeof(this) opAdd(typeof(this) that) // immutable
        {
            typeof(this) result;
            result.value = this.value + that.value;
            return result;
        }
    }
}

alias ExampleTemplate!int Example;
immutable immutableEx = Example(1);
Example ex = Example(1);
Example ex2 = immutableEx + ex;


I get this error with mutbale opAdd:

example.d(27): Error: mutable method example.ExampleTemplate!int.ExampleTemplate.opAdd is not callable using a immutable object


I get this error with immutable opAdd
-------~-------+-------~-------=-------~-------+-------~-------
example.d(18): Error: cannot modify immutable expression
result.value
example.d(27): Error: template instance
example.ExampleTemplate!int error instantiating


I get that typeof(this) is immutable ExampleTemplate!int.
I can't find any way to cast immutable away because
typeof(this) is the only way I know to get the type.

Any help would be greatly appreciated!

____________________________________________________________
Can't remember your password? Do you need a strong and secure password?
Use Password manager! It stores your passwords & protects your account.
Check it out at http://mysecurelogon.com/manager



December 28, 2014
On Sunday, 28 December 2014 at 22:07:31 UTC, AuoroP via
Digitalmars-d-learn wrote:
> I have been trying to figure templates out...
>
> template ExampleTemplate(T)
> {
>     struct ExampleTemplate
>     {
>         T value;
>
>         // constructor
>         auto this(T value)
>         {
>             this.value = value;
>             return this;
>         }

Constructor should not have a return value.

>
>         // opAdd
>         typeof(this) opAdd(typeof(this) that) // immutable
>         {
>             typeof(this) result;
>             result.value = this.value + that.value;
>             return result;
>         }
>     }
> }
>
> alias ExampleTemplate!int Example;
> immutable immutableEx = Example(1);
> Example ex = Example(1);
> Example ex2 = immutableEx + ex;
>
>
> I get this error with mutbale opAdd:
>
> example.d(27): Error: mutable method
> example.ExampleTemplate!int.ExampleTemplate.opAdd is not
> callable using a immutable object

This is because you can only call member functions that are
marked with immutable, if your instance is immutable.

pragma(msg, typeof(this)) will print the type of this at compile
time.


> I get this error with immutable opAdd
> -------~-------+-------~-------=-------~-------+-------~-------
> example.d(18): Error: cannot modify immutable expression
> result.value
> example.d(27): Error: template instance
> example.ExampleTemplate!int error instantiating

This is because typeof(this) is immutable.

>
> I get that typeof(this) is immutable ExampleTemplate!int.
> I can't find any way to cast immutable away because
> typeof(this) is the only way I know to get the type.

Well, the type is ExampleTemplate. No reason not to write it
directly. If you cannot for whatever reason I currently do not
see: cast to Unqual!(typeof(this)).
See http://dlang.org/phobos/std_traits.html
December 28, 2014
>
> Well, the type is ExampleTemplate. No reason not to write it
> directly. If you cannot for whatever reason I currently do not
> see: cast to Unqual!(typeof(this)).
> See http://dlang.org/phobos/std_traits.html

Also: Casting with no Type or CastQual removes any top level
const, immutable, shared or inout type modifiers from the type of
the UnaryExpression.

shared int x;
assert(is(typeof(cast()x) == int));
December 28, 2014
On Sunday, 28 December 2014 at 22:07:31 UTC, AuoroP via
Digitalmars-d-learn wrote:
> I have been trying to figure templates out...
>
> template ExampleTemplate(T)
> {
>     struct ExampleTemplate
>     {
>         T value;
>
>         // constructor
>         auto this(T value)

Constructors don't have return types.

>         {
>             this.value = value;
>             return this;

Constructors don't return.

>         }
>
>         // opAdd
>         typeof(this) opAdd(typeof(this) that) // immutable
>         {
>             typeof(this) result;
>             result.value = this.value + that.value;
>             return result;
>         }
>     }
> }
>
> alias ExampleTemplate!int Example;
> immutable immutableEx = Example(1);
> Example ex = Example(1);
> Example ex2 = immutableEx + ex;
>
>
> I get this error with mutbale opAdd:
>
> example.d(27): Error: mutable method
> example.ExampleTemplate!int.ExampleTemplate.opAdd is not
> callable using a immutable object
>
>
> I get this error with immutable opAdd
> -------~-------+-------~-------=-------~-------+-------~-------
> example.d(18): Error: cannot modify immutable expression
> result.value
> example.d(27): Error: template instance
> example.ExampleTemplate!int error instantiating
>
>
> I get that typeof(this) is immutable ExampleTemplate!int.
> I can't find any way to cast immutable away because
> typeof(this) is the only way I know to get the type.

The type is ExampleTemplate, so:
             ExampleTemplate result;

But if you actually need to, you can use std.traits.Unqual to get
the unqualified version of a type:
             import std.traits: Unqual;
             Unqual!(typeof(this)) result;
December 29, 2014

> -----Original Message-----
> From: digitalmars-d-learn@puremagic.com
> Sent: Sun, 28 Dec 2014 22:18:43 +0000
> To: digitalmars-d-learn@puremagic.com
> Subject: Re: Problem with immutables and Template typeof(this)
> 
> On Sunday, 28 December 2014 at 22:07:31 UTC, AuoroP via Digitalmars-d-learn wrote:
>> I have been trying to figure templates out...
>> 
>> template ExampleTemplate(T)
>> {
>>     struct ExampleTemplate
>>     {
>>         T value;
>> 
>>         // constructor
>>         auto this(T value)
>>         {
>>             this.value = value;
>>             return this;
>>         }
> 
> Constructor should not have a return value.
> 

Thank you!

>> 
>>         // opAdd
>>         typeof(this) opAdd(typeof(this) that) // immutable
>>         {
>>             typeof(this) result;
>>             result.value = this.value + that.value;
>>             return result;
>>         }
>>     }
>> }
>> 
>> alias ExampleTemplate!int Example;
>> immutable immutableEx = Example(1);
>> Example ex = Example(1);
>> Example ex2 = immutableEx + ex;
>> 
>> 
>> I get this error with mutbale opAdd:
>> 
>> example.d(27): Error: mutable method example.ExampleTemplate!int.ExampleTemplate.opAdd is not callable using a immutable object
> 
> This is because you can only call member functions that are marked with immutable, if your instance is immutable.
> 
> pragma(msg, typeof(this)) will print the type of this at compile
> time.
> 

Thank you, that is easier than my method:

// opDbg
typeof(this) opDbg() immutable
{
    writeln( typeof(this).stringof );
    return this;
}

> 
>> I get this error with immutable opAdd
>> -------~-------+-------~-------=-------~-------+-------~-------
>> example.d(18): Error: cannot modify immutable expression
>> result.value
>> example.d(27): Error: template instance
>> example.ExampleTemplate!int error instantiating
> 
> This is because typeof(this) is immutable.
> 
>> 
>> I get that typeof(this) is immutable ExampleTemplate!int.
>> I can't find any way to cast immutable away because
>> typeof(this) is the only way I know to get the type.
> 
> Well, the type is ExampleTemplate. No reason not to write it
> directly. If you cannot for whatever reason I currently do not
> see: cast to Unqual!(typeof(this)).
> See http://dlang.org/phobos/std_traits.html

I tried this and it works!!! I just don't get why it works. It /is/ a type but it seems a parameter short of being useful! I definitely wouldn't have tried it on my own so I'm really thankful for that!

____________________________________________________________
FREE 3D EARTH SCREENSAVER - Watch the Earth right on your desktop!
Check it out at http://www.inbox.com/earth



December 29, 2014

> -----Original Message-----
> From: digitalmars-d-learn@puremagic.com
> Sent: Sun, 28 Dec 2014 22:21:20 +0000
> To: digitalmars-d-learn@puremagic.com
> Subject: Re: Problem with immutables and Template typeof(this)
> 
> On Sunday, 28 December 2014 at 22:07:31 UTC, AuoroP via Digitalmars-d-learn wrote:
>> I have been trying to figure templates out...
>> 
>> template ExampleTemplate(T)
>> {
>>     struct ExampleTemplate
>>     {
>>         T value;
>> 
>>         // constructor
>>         auto this(T value)
> 

I also wanted to thank you for your very helpful answer!

____________________________________________________________
FREE 3D EARTH SCREENSAVER - Watch the Earth right on your desktop!
Check it out at http://www.inbox.com/earth



December 30, 2014
On 12/28/2014 02:07 PM, AuoroP via Digitalmars-d-learn wrote:

> I have been trying to figure templates out...

Although the question has already been answered, here is a solution that combines most of the suggestions that have already been made. It does not need any kind of casting:

/* Eponymous template syntax is lighter */
struct ExampleTemplate(T)
{
    T value;

    this(T value)
    {
        this.value = value;
    }

    /* 1) As a shorthand, the name of the template is the same
     *    thing as this specific instantiation of it. For
     *    example, if the template is instantiated with "int",
     *    then ExampleTemplate alone means
     *    ExampleTemplate!int.
     *
     * 2) opAdd is marked 'const' so that it can work on
     *    mutable, const, and immutable objects.
     *
     * 3) The parameter is by-copy so that it can take rvalues as well.
     */
    ExampleTemplate opAdd(const(ExampleTemplate) that) const
    {
        return ExampleTemplate(this.value + that.value);

        /* Alternatively:

           auto result = ExampleTemplate(this.value + that.value);
           return result;
        */
    }
}

void main()
{
    /* New alias syntax makes more sense */
    alias Example = ExampleTemplate!int;

    immutable immutableEx = Example(1);
    Example ex = Example(1);
    Example ex2 = immutableEx + ex + immutableEx;
}

Ali