Sign in to follow this  

[g++] "insufficient contextual information to determine type" what a heck?!

This topic is 2321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I compiled this on g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

[code]
template<typename T>
void dummy( T t )
{
}

template void dummy<int>( int );

void dummy2(int i)
{
}


main()
{

void(*fn)()=reinterpret_cast<void(*)()>( dummy<int> );
void(*fn2)()=reinterpret_cast<void(*)()>( static_cast<void(*)(int)>( dummy<int> ));
void(*fn3)()=reinterpret_cast<void(*)()>( dummy2 );
}
[/code]


fn fails with "insufficient contextual information to determine type".
Both fn2 and fn3 compile.
Now, it took me a whole afternoon goggling to find the double cast trick. Why can't g++ figure out the type of dummy<int> by itself???

Share this post


Link to post
Share on other sites
This is the real code
[code]

/******************************************************************************/
class Alarm;
template<typename T>
struct Runalarmcontext{

T* p;
void ( T::* fn )( Alarm* _ap );
};

/*******************************************************************************
*******************************************************************************/
template<typename T>
void alarm_callback( Runalarmcontext<T>* _cp, Alarm* _ap )
{
( ( _cp->p )->*( _cp->fn ) )( _ap );
}

/******************************************************************************/
#define DECLARE_ALARM_CALLBACK( T, fn ) \
qdrive::Runalarmcontext<T> fn##Context; \
void fn( qdrive::Alarm* _ap );


#define CREATE_ALARM( T, _p, _fn, _Delta, _Repeat ) \
( _fn##Context.p = _p, _fn##Context.fn = &T::_fn, \
new qdrive::Alarm( reinterpret_cast<qdrive::Alarm::Callbackfn>( \
static_cast<void(*)( qdrive::Runalarmcontext<T>* _cp, qdrive::Alarm* _ap )>( \
qdrive::alarm_callback<T> )), &_fn##Context, _Delta, _Repeat ))

/******************************************************************************/
class Alarm {

public:

typedef void ( *Callbackfn )( void * _Context, Alarm* _ap ) ;

Alarm( Callbackfn _fn, void* _Context, timeval& _Delta,
bool _Repeat = false );
...
[/code]

When you create an alarm you pass in a static function and a context that will be the parameter of the static function.
Most of the times I would like a class member rather than a static function to handle the callback. So I created all the ugly stuff you see above the class Alarm.
With this in place, if I want the alarm to be handled by Foo::handle_alarm I simply write:
[code]

template
void qdrive::alarm_callback<Foo>( qdrive::Runalarmcontext<Foo>* _cp,
qdrive::Alarm* _ap );


struct Foo{

DECLARE_ALARM_CALLBACK(Foo, handle_alarm)


DECLARE_ALARM_CALLBACK(Foo, handle_alarm2)
...

void Foo::bar()
{

Alarm* p = CREATE_ALARM( Foo, this, handle_alarm,
500, false );
Alarm* p2 = CREATE_ALARM( Foo, this, handle_alarm2,
500, false );
}
[/code]

I am using this to cast away alarm_callback. Maybe there are better ways of accomplishing this.

Share this post


Link to post
Share on other sites
Possibly there are reasons you are avoiding boost. But if there are not, I highly suggest you look into [url="http://www.boost.org/doc/libs/1_47_0/doc/html/function.html"]boost::function[/url] and [url="http://www.boost.org/doc/libs/1_47_0/doc/html/signals.html"]boost::signals[/url]. They will make your life considerably easier.

Share this post


Link to post
Share on other sites

This topic is 2321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this