The following code:
----
template Templ(alias T)
{
alias T!int Templ;
}
class C(T)
{
Templ!C foo;
}
// Uncomment this to make the error go away
//Templ!C foo;
void main()
{
C!int a;
}
----
Gives the error:
----
test.d(3): Error: template instance T is not a template declaration, it is a class
----
When uncommenting the line mentioned in the code the error goes away, presumably because the forward reference goes away.
Comment #1 by robert — 2011-05-12T12:19:19Z
This issue can be worked around using:
----
alias C Workaround;
class C(T)
{
Templ!Workaround foo;
}
----
This shouldn't be needed though.
Comment #2 by kennytm — 2011-05-12T19:35:48Z
This is because that class template is actually
template C(T) {
class C {
<declarations>
}
}
so the C inside is referring to the class C, not the template C. This code works:
class C(T) {
Templ!(.C) foo;
}
I don't know why uncomment the global instantiation makes the problem goes away.
Comment #3 by andrej.mitrovich — 2013-02-09T06:06:21Z
(In reply to comment #2)
> This is because that class template is actually
>
> template C(T) {
> class C {
> <declarations>
> }
> }
>
> so the C inside is referring to the class C, not the template C. This code
> works:
>
> class C(T) {
> Templ!(.C) foo;
> }
>
> I don't know why uncomment the global instantiation makes the problem goes
> away.
Yeah, this is an accepts-invalid for this test-case:
template Templ(alias T)
{
alias T!int Templ;
}
class C(T)
{
Templ!(C) foo; // should be NG, must use Templ!(.C)
}
Templ!C foo;
void main()
{
C!int a;
}
Comment #4 by andrej.mitrovich — 2013-02-09T06:08:43Z
(In reply to comment #3)
> Yeah, this is an accepts-invalid for this test-case:
>
> template Templ(alias T)
> {
> alias T!int Templ;
> }
>
> class C(T)
> {
> Templ!(C) foo; // should be NG, must use Templ!(.C)
> }
>
> Templ!C foo;
>
> void main()
> {
> C!int a;
> }
I think the cause could perhaps be a mangling issue or the way the compiler searches for template instances. It finds a 'Templ!C' and decides to use that instead of instantiating a new 'Templ!C', where 'C' is something completely different.
Comment #5 by k.hara.pg — 2013-05-18T03:11:11Z
(In reply to comment #3)
> Yeah, this is an accepts-invalid for this test-case:
>
> template Templ(alias T)
> {
> alias T!int Templ;
> }
>
> class C(T)
> {
> Templ!(C) foo; // should be NG, must use Templ!(.C)
> }
>
> Templ!C foo;
>
> void main()
> {
> C!int a;
> }
No. This is rejects-valid issue. Templ!(C) would capture class C (not template C), BUT, inside Templ, T!int should be translated to the instantiation of template C.
The behavior is consistent with the following:
class C(T) {
void foo() {
C!long c;
// here 'C' points class (not template), but C!long will
// automatically translated to the template C instantiation.
}
}
C!int c;