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