std.traits.ReturnType b0rking on function pointer.

Daniel Keep daniel.keep+lists at gmail.com
Wed Jan 17 22:09:31 PST 2007


Kirk McDonald wrote:
> 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.)

Well, since I'm using Derelict, there isn't a huge amount I can do... 
ok; I *could* go and change all instances of 'typedef' to 'alias'... 
might actually do that and see what happens (but I'd prefer to stick to 
an unmodified version if at all possible).

> 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, ...);
> 

Aww... but the old way was so much purtier...

Anyway, I'll give these a try once I've sufficiently woken up, and let 
you know how it goes.

	-- Daniel


More information about the Digitalmars-d-learn mailing list