im trying to bind a member function to a function pointer that is then registered. there is an error i cannot solve:
Includes :
<functional> and all gcc stdXX (stdio.h, stdlib.h,...)
Callback type to register in atl::hal::lib::uart
void (*f_callback_t)(void* /*data*/, callback_t /*type*/);
My object in atl::hal::obj::uart
class CLI
{
public:
void init()
{
atl::hal::lib::uart::f_callback_t pevt;
// ERROR !!! <----------------------------------------------
pevt = std::bind(
&atl::hal::obj::uart::obj::_eventhandler,
this,
std::placeholders::_1,
std::placeholders::_2);
}
private:
void _eventhandler(
void* data,
atl::hal::lib::uart::callback_t type)
{
M_ASSERT_BOOL(false);
}
}
cannot convert 'std::_Bind_helper<false, void (atl::hal::obj::uart::obj::*)(void*, atl::hal::lib::uart::callback_t), atl::hal::obj::uart::obj*, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type {aka std::_Bind<std::_Mem_fn<void (atl::hal::obj::uart::obj::*)(void*, atl::hal::lib::uart::callback_t)>(atl::hal::obj::uart::obj*, std::_Placeholder<1>, std::_Placeholder<2>)>}' to 'atl::hal::lib::uart::f_callback_t {aka void (*)(void*, atl::hal::lib::uart::callback_t)}' in assignment
You can't store bind results in a simple function pointer type.
You can check whether defined type is a bind_expression (that is, it stores some kind of bind) by using the following type trait:
std::is_bind_expression<bind_type>::value
SHORT SOLUTION:
Just use auto keyword and let the compiler deduce the bind expression type for you.
LONG SOLUTION
Manually define correct type.
For simplified scenario (because you didn't show atl::hal::obj::uart::obj
code), to store a bind to a CLI::_eventhandler
, the final code will look like this:
class CLI
{
public:
using bind_type = decltype(std::bind(std::declval<void (CLI::*)()>(), std::declval<CLI*>(), std::declval<const std::_Ph<1>&>(), std::declval<const std::_Ph<2>&>()));
void init()
{
bind_type pevt1 = std::bind(
&CLI::_eventhandler,
this,
std::placeholders::_1,
std::placeholders::_2);
}
private:
void _eventhandler()
{ }
};
Details:
decltype(std::bind(std::declval<void (CLI::*)()>(), std::declval<CLI*>(), std::declval<const std::_Ph<1>&>(), std::declval<const std::_Ph<2>&>()));
decltype(...)
: Returns type declaration for an expresion inside the brackets. std::bind
: We want the resulting type of std::bind so we must include the call here. std::declval<void (CLI::*)()>()
:
std::declval<T>()
: Simply returns a reference to type T, so that we don't need a dummy object or expression to use inside decltype. std::declval<void (CLI::*)()>()
: returns reference to CLI member function pointer generated by declval, so decltype can deduce it type. std::declval<CLI*>()
: Same as above but returns pointer to CLI* (the *this
pointer argument). std::declval<const std::_Ph<2>&>()
: Placeholder type, I can't really elaborate on that because I extracted it's name from error message. Probably there is a nicer and safer way to define this, maybe someone smarter can help :) std::declval<const std::_Ph<2>&>()
: Second placeholder.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.