I’m working through the excellent Boost Online course that can be found here.
http://en.highscore.de/cpp/boost/
I’m looking at the event handling chapter and have a problem the following code.
Specifically, a member function is called to connect functions to a boost::signal. The signal accepts void functions with no parameters. If the type of the function is a voidf() then boost crashes. If parameter is a template then is works fine.
So with the code:
#include <boost/signal.hpp>
#include <iostream>
#include <typeinfo>
class button
{
public:
//============================
// template versions
// these work ok
template <typename T>
void add_handler_template(T f)
{
std::cout << "In add handler : " << typeid(f).name() << std::endl;
click_.connect(f);
}
template <typename T>
void remove_handler_template(T f)
{
click_.disconnect(f);
}
//============================
// non template versions
// these do not work
void add_handler(void f())
{
std::cout << "In add handler : " << typeid(f).name() << std::endl;
click_.connect(f);
}
void remove_handler(void f())
{
click_.disconnect(f);
}
void click()
{
click_();
}
private:
boost::signal<void ()> click_;
};
void func1()
{
std::cout << "func1." << std::endl;
}
void func2()
{
std::cout << "func2." << std::endl;
}
void func3()
{
std::cout << "func3." << std::endl;
}
int main()
{
button btn;
btn.add_handler(func1);
btn.add_handler(func2);
btn.add_handler(func3);
btn.remove_handler(func2);
btn.click();
return 1;
}
This will throw in on line 111 of function_template.hpp. This is invoked during the singal hander is triger by calling click.
struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
{
static BOOST_FUNCTION_VOID_RETURN_TYPE
invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
BOOST_FUNCTION_PARMS)
{
FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); throw here
}
};
Hoever everything is fine if the template versions of add_handler are called, e.g.
int main()
{
button btn;
btn.add_handler_template(func1);
btn.add_handler_template(func2);
btn.add_handler_template(func3);
btn.remove_handler_template(func2);
btn.click();
return 1;
}
I asumed this is something to do with the type of the function voidf(), but I they are displayed with typeinfo the output if the same.
In add handler : void (__cdecl*)(void)
In add handler : void (__cdecl*)(void)
In add handler : void (__cdecl*)(void)
func1.
func3.
There is obviously something I don’t understand here. Why does add_handler_template() work where add_handler() fails. If anyone could exmple that would be very helpfuil.
Compiler VC 2005 on XP, boost version 1_38
Thanks in advance
G87