Problem with templates
Sean Reque
seanthenewt at yahoo.com
Mon Jul 7 09:26:27 PDT 2008
Thanks for your response, Jarret.
>
> Even if your template did work, unless you're using D2, it will fail
> spectacularly at runtime since you're returning a delegate, and when you try
> to call said delegate it will simply give garbage or crash the program as it
> is trying to access the 'first' and 'second' locals off the stack which no
> longer exist.
>
I am using D 2.0, so I should be getting full closure support. But I am not yet even getting past the compile stage.
> I tried compiling your code just using some D functions and ran into two
> issues:
>
> 1. The delegate that you return doesn't return anything. It should be
> "return second(first(args));" but that's probably just a typo.
Heh, thanks :). I have been programming in Ruby and Perl a lot lately, where the return keyword isn't necessary.
> 2. The compiler ICEs once that's fixed. If the T parameter is changed to a
> non-tuple, it "works" (but again, in D1 the resulting delegate is invalid
> and gives garbage).
>
> Another way to implement compose involves creating a static function, which
> will probably be a bit faster too.
>
> import tango.io.Stdout;
> import tango.core.Traits;
>
> ReturnTypeOf!(f2) compose(alias f1, alias f2)(ParameterTupleOf!(f1) p)
> {
> return f2(f1(p));
> }
>
> void main(char[][] args)
> {
> int foo(double x) { return cast(int)x; }
> int bar(int x) { return x * x; }
>
> Stdout.formatln("{}", compose!(foo, bar)(4.5));
> }
>
> This should also work with C functions, no problem.
>
> If you're using Phobos, you'd instead import std.traits, use "ReturnType"
> instead of "ReturnTypeOf", and "ParameterTypeTuple" instead of
> "ParameterTupleOf".
>
I tried writing the compose function to return a static function. Here is the new function:
ReturnType!(f2) my_compose2(alias f1, alias f2)(ParameterTypeTuple!(f1) args) {
return second(first(args));
}
I again try to compose the functions and invoke them, this time like so:
my_compose2!(&SQLAllocHandle, &SQL)(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
Again, I get this error message:
test.d(41): template test.my_compose2(alias f1,alias f2) does not match any function template declaration
test.d(41): template test.my_compose2(alias f1,alias f2) cannot deduce template function from argument types !(& SQLAllocHandle,& SQL)(const(short),const(void*),void**)
I still am not sure why my original compose function didn't work, either. Someone else posted that I should try using function inputs, but I thought that D could implicitly convert function pointers to delegates.
Perhaps I am doing something else wrong, or making an incorrect assumption? Also, creating a static function that returns a value isn't sufficient for what I need. Basically I want to be able to create D versions of every C ODBC call I need that will check the return values of these functions and throw an exception on error. I could do that manually for each function, but then I might as well be coding in C or C++ :).
More information about the Digitalmars-d-learn
mailing list