Thread overview
Some ideas and a bug in template compilation
Dec 02, 2002
Daniel Yokomiso
Dec 04, 2002
Walter
Dec 04, 2002
Daniel Yokomiso
Dec 08, 2002
Walter
December 02, 2002
Hi,

    While I was trying to circumvent the current template semantics, I got
stuck in the following problem. If I define a template like this:


template A(T, U) {
    private U u = new U();
}


    The compiler says "non-constant expression new U". IIRC templates don't
have a constructor, but I think they should have a constructor to initialize
template variables (hint or forget about templates and let us have generic
modules ;-) ).
    I got around this problem creating a setter for u, so the template user
must call setU explicitly. But this led to another problem. Suppose I have a
set of templates like this:


template A(T) {
    public interface Init {
        public T init();
    }
}
template A(T : int) {
    public class Init {
        public T init() {
            return 42;
        };
    }
}
template A(T : float) {
    public class Init {
        public T init() {
            return 3.14159;
        };
    }
}

template TB(T, U) {
    private U initializer;
    private void setInitializer(U init) {
        initializer = init;
    }
    public class B {
        private T _value;
        public this() {
            this._value = initializer.init();
        }
        public T value() {
            return this._value;
        }
    }
}
template TB(T) {
    private instance TB(T, instance A(T).Init) tb;
    private void setInitializer(instance A(T).Init init) {
        tb.setInitializer(init);
    }
    public class B : tb.B {
    }
}

int main() {
    instance TB(int, instance A(int).Init) tb;
    tb.setInitializer(new instance A(int).Init());
    tb.B b = new tb.B();
    printf("b.value -> %d\r\n", b.value());

    instance TB(float) tb2;
    tb2.setInitializer(new instance A(float).Init());
    tb2.B b2 = new tb2.B();
    printf("b2.value -> %e\r\n", b2.value());

    return 0;
}


    In this case U is a initializer type, and the A template can predefine
some common template specializations, and let the user create their own,
using a subclass for the Init interface. This code compiles and runs
correctly. But what I really needed was a default parameters in templates or
a "subtemplate", instead of this delegation trick. This could be useful
sometimes, but I'm not sure about this.
    Anyway, while I was writing this code example I forgot to type the
instance in the second TB definition usage of template A:


    private instance TB(T, A(T).Init) tb;


    And this made the compiler crash when it was parsing the file. But if we
forgot the instance in the main function:


    instance TB(int, A(int).Init) tb;


the following message is given: "found 'int' when expecting ')'". I don't think this is the correct error  message, but at least it didn't crash.

    Best regards,
    Daniel Yokomiso.

"Clothes make the man. Naked people have little or no influence in society." - Mark Twain


December 04, 2002
"Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:asgeg7$1df$1@digitaldaemon.com...
> Hi,
>
>     While I was trying to circumvent the current template semantics, I got
> stuck in the following problem. If I define a template like this:
>
>
> template A(T, U) {
>     private U u = new U();
> }
>
>
>     The compiler says "non-constant expression new U". IIRC templates
don't
> have a constructor, but I think they should have a constructor to
initialize
> template variables (hint or forget about templates and let us have generic
> modules ;-) ).

Try adding:
    this()
    {
        u = new U();
    }
to the body of the template.

>     I got around this problem creating a setter for u, so the template
user
> must call setU explicitly. But this led to another problem. Suppose I have
a
> set of templates like this:
>
>
> template A(T) {
>     public interface Init {
>         public T init();
>     }
> }
> template A(T : int) {
>     public class Init {
>         public T init() {
>             return 42;
>         };
>     }
> }
> template A(T : float) {
>     public class Init {
>         public T init() {
>             return 3.14159;
>         };
>     }
> }
>
> template TB(T, U) {
>     private U initializer;
>     private void setInitializer(U init) {
>         initializer = init;
>     }
>     public class B {
>         private T _value;
>         public this() {
>             this._value = initializer.init();
>         }
>         public T value() {
>             return this._value;
>         }
>     }
> }
> template TB(T) {
>     private instance TB(T, instance A(T).Init) tb;
>     private void setInitializer(instance A(T).Init init) {
>         tb.setInitializer(init);
>     }
>     public class B : tb.B {
>     }
> }
>
> int main() {
>     instance TB(int, instance A(int).Init) tb;
>     tb.setInitializer(new instance A(int).Init());
>     tb.B b = new tb.B();
>     printf("b.value -> %d\r\n", b.value());
>
>     instance TB(float) tb2;
>     tb2.setInitializer(new instance A(float).Init());
>     tb2.B b2 = new tb2.B();
>     printf("b2.value -> %e\r\n", b2.value());
>
>     return 0;
> }
>
>
>     In this case U is a initializer type, and the A template can predefine
> some common template specializations, and let the user create their own,
> using a subclass for the Init interface. This code compiles and runs
> correctly. But what I really needed was a default parameters in templates
or
> a "subtemplate", instead of this delegation trick. This could be useful
> sometimes, but I'm not sure about this.
>     Anyway, while I was writing this code example I forgot to type the
> instance in the second TB definition usage of template A:
>
>
>     private instance TB(T, A(T).Init) tb;
>
>
>     And this made the compiler crash when it was parsing the file. But if
we
> forgot the instance in the main function:
>
>
>     instance TB(int, A(int).Init) tb;
>
>
> the following message is given: "found 'int' when expecting ')'". I don't think this is the correct error  message, but at least it didn't crash.



December 04, 2002
"Walter" <walter@digitalmars.com> escreveu na mensagem news:askkmp$1vqc$1@digitaldaemon.com...

[snip]

> Try adding:
>     this()
>     {
>         u = new U();
>     }
> to the body of the template.

    The compiler says: "constructor this constructors only are for class
definitions".




December 08, 2002
I shall have to fix that. -Walter

"Daniel Yokomiso" <daniel_yokomiso@yahoo.com.br> wrote in message news:asl7ik$2lno$1@digitaldaemon.com...
>
> "Walter" <walter@digitalmars.com> escreveu na mensagem news:askkmp$1vqc$1@digitaldaemon.com...
>
> [snip]
>
> > Try adding:
> >     this()
> >     {
> >         u = new U();
> >     }
> > to the body of the template.
>
>     The compiler says: "constructor this constructors only are for class
> definitions".
>
>
>
>