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