Вопрос

In D, when a template has a member with the same name as the template, any instantiation of the template refers directly to that member. But if that member is itself a template, I cannot immediately instantiate it for some reason. Creating an intermediate alias works, however.

template Foo(int x){
  template Foo(int y){
     enum int Foo = x+y;
  }
}
alias Foo1 = Foo!(1);
assert(Foo1!(2) == 3); // ok
int a = Foo!(1)!(1); // compile error Error: found '!' when expecting ')'

Why does this fail? Is there any way around this?

My goal is neatness and currying.

Это было полезно?

Решение

This is how D grammar is defined. Current compiler shows correct error message:

Error: multiple ! arguments are not allowed

Also this question is already filed as Issue 1566 and from issue comment 4:

If I don't miss something multiple ! is considered harmful as A!B!C may be considered as A instantiated with B!C or A!B instantiated with C. Also requirement to always have parantheses in such case may be added but IMO it doesn't look like a worthwhile language complication as it isn't generally needed.

This can be workarounded by e.g. such Inst template:

template Foo(int x)
{ enum int Foo(int y) = x + y; }

alias Inst(alias Template, A...) = Template!A;

enum a = Inst!(Foo!1, 1);

Note D now has a new short template declaration syntax and also one doesn't need to use parantheses in case template argument is an identifier or a constant.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top