std.traits.ReturnType b0rking on function pointer.

Kirk McDonald kirklin.mcdonald at gmail.com
Wed Jan 17 12:28:34 PST 2007


Daniel Keep wrote:
> Kirk McDonald wrote:
> 
>> Daniel Keep wrote:
>>
>>>
>>> Hey there, I'm having problems with getting the return type of a 
>>> function pointer.  Basically, I want to do this:
>>>
>>> template SDL_SafeCall(alias tFn)
>>> {
>>>     ReturnType!(SDL_SetVideoMode) SDL_SafeCall(...)
>>>     {
>>>         ...
>>>     }
>>> }
>>> SDL_SafeCall!(SDL_SetVideoMode)(...);
>>>
>>> where SDL_SetVideoMode is declared like so (yes, it's DerelictSDL):
>>>
>>> typedef SDL_Surface* function(int,int,int,Uint32) pfSDL_SetVideoMode;
>>> pfSDL_SetVideoMode          SDL_SetVideoMode;
>>>
>>> When I try to compile my code, I get the following errors:
>>>
>>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias 
>>> std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias 
>>> declaration
>>> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): template instance 
>>> std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
>>>
>>> I've tried writing my own version, but that didn't do any better. 
>>> Anyone have any ideas?
>>>
>>>     -- Daniel
>>
>>
>>
>> ReturnType has two forms: One which is intended to operate on a 
>> function pointer or delegate /type/, and one which is intended to 
>> operate on a function alias.
>>
>> SDL_SetVideoMode is a function pointer. You want to pass its /type/ to 
>> ReturnType. By passing it directly, it gets sent to the alias form of 
>> ReturnType, which confuses it greatly. Try this:
>>
>> ReturnType!(typeof(SDL_SetVideoMode))
>>
> 
> template SDL_Refcall(alias tFn)
> { // line 57
>     ReturnType!(typeof(tFn)) SDL_Refcall(tArgs...)(tArgs args)
>     {
>         ReturnType!(typeof(tFn)) r = tFn(args);
>         if( r is null )
>             throw new SDLException(tFn.nameof, 0);
>         else
>             return r;
>     }
> }
> 
> SDL_Refcall!(SDL_SetVideoMode)(...);
> 
> No good.
> 
> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(34): alias 
> std.traits.ReturnType!(pfSDL_SetVideoMode).ReturnType recursive alias 
> declaration
> C:\Daniel\dmd\dmd\src\phobos\std\traits.d(58): template instance 
> std.traits.ReturnType!(pfSDL_SetVideoMode) error instantiating
> src\engine\shared_sdl\shared_sdl.d(58): Error: 
> ReturnType!(pfSDL_SetVideoMode) is used as a type

I have two thoughts:

pfSDL_SetVideoMode is declared as a typedef. Maybe try it as an alias? 
ReturnType just uses the "return" TypeSpecialization in the 
IsExpression, which might get confused by typedefs. (I have not tested 
this.)

Second, you are passing in a (global?) variable as a template alias 
parameter. While this is technically allowed, I have had nothing but 
grief doing that sort of thing. I suggest re-writing it as:

ReturnType!(fn_t) SDL_Refcall(fn_t, tArgs ...) (fn_t fn, tArgs args) {
     // stuff...
}

And then calling it as a regular function template:

SDL_Refcall(SDL_SetVideoMode, ...);

-- 
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org


More information about the Digitalmars-d-learn mailing list