Thread overview
Why are template alias parameters broken?
Aug 27, 2021
Menshikov
Aug 27, 2021
Menshikov
Aug 27, 2021
Menshikov
Aug 27, 2021
Menshikov
Aug 27, 2021
Menshikov
August 27, 2021

It's work:

template Foo(alias var)
{
    void inc() { var++; }
}

void main()
{
    int v = 4;
    alias foo = Foo!(v);
    foo.inc();
    assert(v == 5);
}

But it doesn't work:

template Foo(alias var)
{
    void inc() { var++; }
}

void main()
{
    struct V{
      int a;
    }
    auto v = V(4);
    alias foo = Foo!(v.a);
    foo.inc();//err
    assert(v.a == 5);
}

Hence this applies to Alias!() and AliasSeq!()

August 27, 2021

On Friday, 27 August 2021 at 18:47:56 UTC, Menshikov wrote:

>

It's work:

template Foo(alias var)
{
    void inc() { var++; }
}

void main()
{
    int v = 4;
    alias foo = Foo!(v);
    foo.inc();
    assert(v == 5);
}

But it doesn't work:

template Foo(alias var)
{
    void inc() { var++; }
}

void main()
{
    struct V{
      int a;
    }
    auto v = V(4);
    alias foo = Foo!(v.a);
    foo.inc();//err
    assert(v.a == 5);
}

Hence this applies to Alias!() and AliasSeq!()

And it doesn't work

template Foo(alias var)
{
    void inc() { var++; }//err
}

void main()
{
    static struct V{
      int a;
    }
    auto v = V(4);
    mixin Foo!(v.a)foo;//err
    foo.inc();
    assert(v.a == 5);
}
August 27, 2021

On Friday, 27 August 2021 at 19:00:27 UTC, Menshikov wrote:

>

On Friday, 27 August 2021 at 18:47:56 UTC, Menshikov wrote:

>

It's work:

template Foo(alias var)
{
    void inc() { var++; }
}

void main()
{
    int v = 4;
    alias foo = Foo!(v);
    foo.inc();
    assert(v == 5);
}

But it doesn't work:

template Foo(alias var)
{
    void inc() { var++; }
}

void main()
{
    struct V{
      int a;
    }
    auto v = V(4);
    alias foo = Foo!(v.a);
    foo.inc();//err
    assert(v.a == 5);
}

Hence this applies to Alias!() and AliasSeq!()

And it doesn't work

template Foo(alias var)
{
    void inc() { var++; }//err
}

void main()
{
    static struct V{
      int a;
    }
    auto v = V(4);
    mixin Foo!(v.a)foo;//err
    foo.inc();
    assert(v.a == 5);
}

We open it ourselves, and it works:

void main()
{
    static struct V{
      int a;
    }
    auto v = V(4);
    void inc() { v.a++; }
    inc();
    assert(v.a == 5);
}
August 27, 2021

On 8/27/21 2:47 PM, Menshikov wrote:

>

It's work:

template Foo(alias var)
{
     void inc() { var++; }
}

void main()
{
     int v = 4;
     alias foo = Foo!(v);
     foo.inc();
     assert(v == 5);
}

But it doesn't work:

template Foo(alias var)
{
     void inc() { var++; }
}

void main()
{
     struct V{
       int a;
     }
     auto v = V(4);
     alias foo = Foo!(v.a);
     foo.inc();//err
     assert(v.a == 5);
}

Hence this applies to Alias!() and AliasSeq!()

Aliases to expressions don't work. They have to be symbols, type keywords (e.g. int), or compile-time values. v.a is an expression.

It's quite an annoying limitation, I agree.

To work around, you can do:

template Foo(alias var)
{
   void inc() {var.a++}
}

and then pass v instead of v.a.

-Steve

August 27, 2021

On 8/27/21 3:14 PM, Steven Schveighoffer wrote:

>

To work around, you can do:

template Foo(alias var)
{
    void inc() {var.a++}
}

and then pass v instead of v.a.

Another possible workaround:

auto v = V(4);
ref int a() { return v.a; }
alias foo = Foo!a;
foo.inc();

-Steve

August 27, 2021

On Friday, 27 August 2021 at 19:32:49 UTC, Steven Schveighoffer wrote:

>

On 8/27/21 3:14 PM, Steven Schveighoffer wrote:

>

To work around, you can do:

template Foo(alias var)
{
    void inc() {var.a++}
}

and then pass v instead of v.a.

Another possible workaround:

auto v = V(4);
ref int a() { return v.a; }
alias foo = Foo!a;
foo.inc();

-Steve

Thanks

August 27, 2021

On Friday, 27 August 2021 at 20:07:06 UTC, Menshikov wrote:

>

Thanks

it would be cool if template alias parameters could work with expressions. And whether it would break the previous code.