August 02, 2007
Jarrett Billingsley Wrote:


> I'm going to have to see some of your code.  This works fine for me:
> 
> template Templ(T : U function(V), U, V...)
> {
>     const Templ = T.stringof;
> }
> 
> void main()
> {
>     pragma(msg, Templ!(int function(float)));
>     pragma(msg, Templ!(void function(char[], int[char[]])));
> }
for me this outputs "Error: string expected for message not Templ"

this is the code that I used (and failed):
template Templ(T : U function(V), U, V...)
{
    T f;
    U call(V v) { return f(v);}
}

void func(int i, float f, char[] s) {
	writefln(i, f, s);
}

void main()
{
	alias Templ!(void function(int, float, char[])) TemplTest;
	TemplTest.f = &func;
	TemplTest.call(1, 1.0, "1");
}

the error messages were:

main.d(11): Error: expected 3 arguments, not 0
main.d(20): template instance main.Templ!(void(*)(int, float, char[])) error instantiating
main.d(21): Error: template instance 'Templ!(void(*)(int, float, char[]))' is not a variable
main.d(21): Error: no property 'f' for type 'int'
main.d(21): Error: constant (Templ!(void(*)(int, float, char[]))).f is not an lvalue
main.d(21): Error: cannot implicitly convert expression (& func) of type void(*)(int, float, char[]) to int
main.d(22): Error: template instance 'Templ!(void(*)(int, float, char[]))' is not a variable
main.d(22): Error: no property 'call' for type 'int'
main.d(22): Error: function expected before (), not 1 of type int
> 

> > on that note, if you have a function int func(); and evaluate typeid(typeof(func)) you get the type int() which is odd since func is evaluated the same as func() so the type should just be int
> 
> Again, I'm going to have to see code.  function int func() is an incomplete function literal.  It means nothing and does not compile.  However if you write "int function() func;" and then get the typeid(typeof(func)), it's "int()*" (that is a pointer to a function which takes nothing and returns an int), which makes sense because the "call a function without parens" does not apply to function _pointers_, only _functions_ (there's a use for that function type!).
> 
> 
heres the code:

int Foo() {return 1;}

void main() {
	writefln(typeid(typeof(Foo)));
}

prints int()

writefln(typeof(Foo));

gives "Error: type int() is not an expression"

writefln(typeid(Foo));

gives the error: "function main.Foo is used as a type"

August 02, 2007
"Ender KaShae" <astrothayne@gmail.com> wrote in message news:f8t0t1$1m93$1@digitalmars.com...
>> template Templ(T : U function(V), U, V...)
>> {
>>     const Templ = T.stringof;
>> }
>>
>> void main()
>> {
>>     pragma(msg, Templ!(int function(float)));
>>     pragma(msg, Templ!(void function(char[], int[char[]])));
>> }
> for me this outputs "Error: string expected for message not Templ"

You must have an old compiler then.  This works fine with DMD 1.020 and should work in 2.003 by proxy.

> this is the code that I used (and failed):
> template Templ(T : U function(V), U, V...)
> {
>    T f;
>    U call(V v) { return f(v);}
> }

I think you may have found a bug here.  For some reason, T is correct, U is correct, but V ends up as an empty tuple every time.  Odd.

> int Foo() {return 1;}
>
> void main() {
> writefln(typeid(typeof(Foo)));
> }
>
> prints int()

I see what you're saying now, and it's actually not ambiguous.  See, the "function call without parens" only comes into effect when symbol lookup finds that the symbol is a function type, but the destination is a different type.  Then it implicitly inserts the parens and tries to do semantic analysis on it again.  However, inside typeof(), there's no ambiguity; typeof(Foo) just means "the type of the symbol Foo".  However, if you do something like "writefln(typeid(typeof(Foo + 1)))" _now_ the implicit function call kicks in, and you get "int".

> writefln(typeof(Foo));
>
> gives "Error: type int() is not an expression"

Makes sense, you can't use a type as an expression.

> writefln(typeid(Foo));
>
> gives the error: "function main.Foo is used as a type"

Again makes sense, as Foo refers to a function, and not a type.