GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 24-Aug-2006, 11:45
edt edt is offline
New Member
 
Join Date: Aug 2006
Posts: 26
edt is on a distinguished road

Callback parameters


I'm implementing a templated C++ class for managing callback ptrs, and I need a function to call them all so the inheriting class doesn't need implementation details of the list. The trouble is there are different numbers and types of parameters. The inheriting class and the calling context will know the number and type, but I just want a method to call each callback and pass its parameters straight through. Here's what I mean:
CPP / C++ / C Code:
template <class CB_TYPE>
class CB_Handler {
   void call_cbs(...);
};

template <class CB_TYPE>
void CB_Handler<CB_TYPE>::call_cbs(...) {
   /* ... for each cb in the list ... */
      (*cur_cb) (...);   // these parameters should be the same as the call
}

typedef void (*my_cb) (int num, char* lbl);   // available to ClassA and main,
   // but not to CB_Handler

class ClassA : public CB_Handler<my_cb> {
   void call_my_cbs(int num, char* lbl);
};

void ClassA::call_my_cbs(int num, char* lbl) {
   call_cbs(num, lbl);
}
stdarg almost works, but it would make the inheriting class and handler class much too complicated having to manually communicate the callback's footprint.
Last edited by LuciWiz : 24-Aug-2006 at 15:03. Reason: Please insert your C/C++ code between [cpp] & [/cpp] tags
  #2  
Old 24-Aug-2006, 19:12
davis
 
Posts: n/a

Re: Callback parameters


The basis of your problem is that callbacks are inherently not type safe. This is the underlying issue behind the numerous "meta" compilers in such code that must be both type safe and facilitate an unknown set of arguments (interface freedom).

However, stating this, you can elect to use a prototypical base class passing in any derived that will meet the requirements for the base's PVF "entry points" such that your users (other code) that needs to receive the benefit of the "callback service" can package their bundles into the derived and invoke the "expositionary operations" using the prototypical entry point.

This is sometimes handled through a class hierarchy that exploits the virtual function table and offers it through a meta datatype that is basically an enumeration of interfaces qualified at component design-time. As you probably know, few such manufacturers of commerical libraries avoid the need for the meta compiler, which adds complexity to the code and coding process, but grants true interface signature freedom.

In other words, avoid callbacks. They're not type safe unless all of the types are known at compile time.


:davis:
  #3  
Old 25-Aug-2006, 13:44
edt edt is offline
New Member
 
Join Date: Aug 2006
Posts: 26
edt is on a distinguished road

Re: Callback parameters


I know they're not type safe, but callbacks are a huge help in decoupling, and I think I'm using them pretty safely.

I managed to get around my problem after several hours of hacking and googling. I think what I'm doing is similar to what you're suggesting. I've got a templated base class for each number of parameters that defines the types and keeps things pretty-much type safe. This still requires major code duplication and an assumption of the maximum number of parameters, but it's a step in the right direction. I've still got a void* parameter, but I think it'll be much easier for now, and if I need later I can weed it out with class hierarchies, too.

The frustrating thing is that my whole problem could have been solved with a few lines of Python instead of several files of C++:
Python Code:
def send_msg(*args):
   for cb in cb_list:
      cb(*args)
It completely ignores type safety, but I love Python... =)

But one thing I am still wondering (may not even help me anymore) is about specialization with a templated parameter. I found one thread about this somewhere else, but it didn't have a solution I could understand. Here's sort of what I mean:
CPP / C++ / C Code:
template <typename T> struct A {
   void do_thing();
};

template <typename T> A<T>::do_thing() {}

// not sure if the syntax is right, but the type is another A with
// its own generic type T
template <typename T> A<A<T> >::do_thing() {
   T thingy;
   // etc...
}
This won't compile, whereas (in place of that last definition):
CPP / C++ / C Code:
template <> A<A<int> >::do_thing() {
   int thingy;
   // etc...
}
did compile (I think).

Really confusing, I know, but what gives?
  #4  
Old 28-Aug-2006, 06:28
LuciWiz's Avatar
LuciWiz LuciWiz is offline
Moderator
 
Join Date: Jul 2004
Location: Cluj-Napoca (Romania)
Posts: 1,031
LuciWiz is a jewel in the roughLuciWiz is a jewel in the roughLuciWiz is a jewel in the roughLuciWiz is a jewel in the rough

Re: Callback parameters


Quote:
Originally Posted by edt
This won't compile, whereas (in place of that last definition):
CPP / C++ / C Code:
template <> A<A<int> >::do_thing() {
   int thingy;
   // etc...
}
did compile (I think).

What do you mean by "I think"? It either compiles or it doesn't... I don't get it.

Doesn't your compiler issue an error regarding "redefinition" or something along those lines?

Hint: what is the default return type for a function when you didn't specify it?

Best regards,
Lucian
__________________
Please read these Guidelines before posting on the forum

"A person who never made a mistake never tried anything new."
Einstein
  #5  
Old 28-Aug-2006, 11:43
edt edt is offline
New Member
 
Join Date: Aug 2006
Posts: 26
edt is on a distinguished road

Re: Callback parameters


I said "I think" because
a) I didn't try to compile that exact code, just something very similar, and
b) I can't be positive it's doing what I think it is in the way I think it is.

I use gcc/g++, and it does give redefinition errors when something's redefined, but it didn't on that second definition.

I'll make sure that exact code compiles and check on that default return type when I get a free moment, but I expect if I didn't specify a return type at all it would create a compiler error for the missing typename. What do you mean by "didn't specify" and how does it apply?
  #6  
Old 28-Aug-2006, 13:26
LuciWiz's Avatar
LuciWiz LuciWiz is offline
Moderator
 
Join Date: Jul 2004
Location: Cluj-Napoca (Romania)
Posts: 1,031
LuciWiz is a jewel in the roughLuciWiz is a jewel in the roughLuciWiz is a jewel in the roughLuciWiz is a jewel in the rough

Re: Callback parameters


Quote:
Originally Posted by edt
What do you mean by "didn't specify" and how does it apply?

Here is what I mean: it is legal in C++ to declare a function like this:

CPP / C++ / C Code:
f()
{
    //do some stuff
}

My question is : what return type will the compiler generate for this function? And what return type did you specify for your do_thing() function in the structure?
__________________
Please read these Guidelines before posting on the forum

"A person who never made a mistake never tried anything new."
Einstein
  #7  
Old 28-Aug-2006, 16:05
edt edt is offline
New Member
 
Join Date: Aug 2006
Posts: 26
edt is on a distinguished road

Re: Callback parameters


Oh, right. I forgot the return types in the post. It should have been:
CPP / C++ / C Code:
template <typename T> void A<A<T> >::do_thing() {
   T thingy;
   // etc...
}
for the first and:
CPP / C++ / C Code:
template <> void A<A<int> >::do_thing() {
   int thingy;
   // etc...
}
for the second (the one that did compile). Sorry for the confusion.

I checked the default return type thing and my compiler said ISO C++ forbids the declaration of 'do_thing' with no type.

But I'm actually asking about the template specialization type, not the return type... It appears to work correctly if I specialize as
CPP / C++ / C Code:
template <> void A<A<int> >::do_thing()
but I can't seem either to specify that I don't care about the type like
CPP / C++ / C Code:
template <> void A<A<> >::do_thing()
or to use a generic type like
CPP / C++ / C Code:
template <type T> void A<A<T> >::do_thing()
Obviously neither of those is valid because they don't compile, but I hope they at least clear up the question.
  #8  
Old 29-Aug-2006, 03:12
LuciWiz's Avatar
LuciWiz LuciWiz is offline
Moderator
 
Join Date: Jul 2004
Location: Cluj-Napoca (Romania)
Posts: 1,031
LuciWiz is a jewel in the roughLuciWiz is a jewel in the roughLuciWiz is a jewel in the roughLuciWiz is a jewel in the rough

Re: Callback parameters


Quote:
Originally Posted by edt
Oh, right. I forgot the return types in the post. It should have been:
CPP / C++ / C Code:
template <typename T> void A<A<T> >::do_thing() {
   T thingy;
   // etc...
}
for the first and:
CPP / C++ / C Code:
template <> void A<A<int> >::do_thing() {
   int thingy;
   // etc...
}
for the second (the one that did compile). Sorry for the confusion.

That is what I was getting at.
BTW, I think in this case thingy should be declared as A<int> thingy;

Quote:
Originally Posted by edt
I checked the default return type thing and my compiler said ISO C++ forbids the declaration of 'do_thing' with no type.

You have a good compiler. Many I have seen (including the one I am currently using) will still (silently) consider int as the default return type, and not generate an error.

Quote:
Originally Posted by edt
But I'm actually asking about the template specialization type, not the return type... It appears to work correctly if I specialize as
CPP / C++ / C Code:
template <> void A<A<int> >::do_thing()
but I can't seem either to specify that I don't care about the type like
CPP / C++ / C Code:
template <> void A<A<> >::do_thing()
or to use a generic type like
CPP / C++ / C Code:
template <type T> void A<A<T> >::do_thing()
Obviously neither of those is valid because they don't compile, but I hope they at least clear up the question.

I understood the question the first time, but I wanted you to first fix your code; if you post code that doesn't compile, the first step is to get it to compile... You obviously are past the beginner level, and know how to declare a function, but I will never understand why people don't use Copy-Paste when posting code. Aren't programmers supposed to be lazy - or is it just me?

The reason what you are trying to do doesn't work is that what you have tried:

CPP / C++ / C Code:
template <typename T> void A<A<T> >::do_thing() {
   T thingy;
   // etc...
}

is not really a valid template specialization. The template argument depends on a generic type, so the compiler can't figure out for which sub-set of types to generate the special code. In the original declaration you wrote a piece of code to be generated for structures of type A instantiated with the generic type T. In your attempt of specialization, you told the compiler to generate code for structures of type A instantiated with another struct A which is instantiated with a generic type T. But isn't the second one a generic type itself?

This will work, for instance:

CPP / C++ / C Code:
struct G {};

template <> void A < A<G> >::do_thing()
{
    A<G> thingy;
}

since the type G is known at compile time, and thus it isn't a generic type.

Best regards,
Lucian
__________________
Please read these Guidelines before posting on the forum

"A person who never made a mistake never tried anything new."
Einstein
  #9  
Old 30-Aug-2006, 09:35
edt edt is offline
New Member
 
Join Date: Aug 2006
Posts: 26
edt is on a distinguished road

Re: Callback parameters


Quote:
Originally Posted by LuciWiz
but I will never understand why people don't use Copy-Paste when posting code.
I normally would, but the code is on a separate box and I would have had to copy the file over samba. That's why it was such a pain to double-check it.

As for the template type, I know I'm specializing with another generic, but since templates compile for each instantiation, I wanted to declare
CPP / C++ / C Code:
A<A<int> > a1;
A<A<float> > a2;
and have the compiler generate both with the same specialization. I could simply specialize each individually, but I think the entire point of templates is to AVOID doing that.
 
 

Recent GIDBlogInstall Adobe Flash - Without Administrator Rights by LocalTech

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Compile Errors due to Default Parameters jdbrine C++ Forum 1 17-Jun-2006 14:45
c function with dynamic set of parameters ? mofta7 C Programming Language 2 05-Jun-2006 07:35
How to design a callback abstraction KiroNeem C++ Forum 1 21-Apr-2006 13:51
callback gmn MS Visual C++ / MFC Forum 0 25-Jun-2004 15:54

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 09:01.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.