In C ++, Boost.Any will allow you to do this in a safe way:
void func(boost::any const &x) { // any_cast a reference and it // will throw if x is not an int. int i = any_cast<int>(x); // any_cast a pointer and it will // return a null pointer if x is not an int. int const *p = any_cast<int>(&x); } // pass in whatever you want. func(123); func("123");
In C, you should use the void pointer:
void func(void const *x) {
You seem to be against this, but I will recommend it anyway: if you use C ++, hug it. Do not be afraid of patterns. Things like Boost.Any and void pointers take place in C ++, but this is very small.
Update
Well, I make small signals - slots - the connection library is used with my gui toolkit. So that I can get rid of Ugly WNDPROC. I need these pointers for connections.
If you need multipurpose signals, Boost.Signals already provides a complete and proven implementation of signals / slots. You can use Boost.Bind (or std::bind if you have a C ++ 0x compiler) to connect member functions:
struct button { boost::signal<void(button&)> on_click; } struct my_window { button b; my_window() { b.on_click.connect(std::bind(&my_window::handle_click, this, std::placeholders::_1)); } void handle_click(button &b) { } void simulate_click() { b.on_click(b); } };
If you need a simple callback, Boost.Function (or std::function , if you have a C ++ 0x compiler) will work well:
struct button { std::function<void(button&)> on_click; } struct my_window { button b; my_window() { b.on_click = std::bind(&my_window::handle_click, this, std::placeholders::_1); } void handle_click(button &b) { } void simulate_click() { b.on_click(b); } };