There are several problems with your code, and I'm pretty certain it never compiled on VisualStudio in its current form. In any case, I can't get it to compile on VS2013. Here are the errors:
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
// ^^^^^^^^
// the member function pointer is a non-type template parameter, remove typename
friend auto createDelegate(ObjType * const p_obj)
// ^^^^
// you've declared this as a friend, but call it within main() as if it is a
// static member function, change 'friend' to 'static'
template< typename ObjType, typename Ret(ObjType::*Method)(Param) >
// ^^^^^^^^
// same as above, remove typename
static Ret ifunction(void * const p_obj, Param&& p_param)
The m_obj
data member is a const
pointer, yet you try to point it to a new object within createDelegate
void * const m_obj = nullptr;
// ^^^^^
// remove the const
After making these changes
template< typename Signature >
class Delegate;
template< typename Ret, typename Param >
class Delegate< Ret(Param) >
{
public:
Ret operator()(Param&& p_param)
{
return m_ifunc(m_obj, std::forward< Param >(p_param));
}
template< typename ObjType, Ret(ObjType::*Method)(Param) >
static auto createDelegate(ObjType * const p_obj)
{
Delegate< Ret(Param) > del;
del.m_obj = p_obj;
del.m_ifunc = &ifunction< ObjType, Method >;
return del;
}
private:
void * m_obj = nullptr;
Ret (*m_ifunc)(void*, Param&&) = nullptr;
template< typename ObjType, Ret(ObjType::*Method)(Param) >
static Ret ifunction(void * const p_obj, Param&& p_param)
{
ObjType * const obj = (ObjType * const) p_obj;
return (obj->*Method)(std::forward< Param >(p_param));
}
};
Now the code compiles, and outputs 5
. Live demo
An additional change is needed for this to compile on VS2013 (release version, don't know about the CTP). Since VS2013 doesn't implement C++14's return type deduction for ordinary functions, createDelegate
needs to have the return type specified explicitly
template< typename ObjType, Ret(ObjType::*Method)(Param) >
static Delegate< Ret(Param) > createDelegate(ObjType * const p_obj)
{ /* ... */ }
Finally, just to make sure you're aware of the alternatives:
Test t;
auto d = std::bind(&Test::test, t, std::placeholders::_1);
d(5); // prints 5
std::function<void(int)> d2 = std::bind(&Test::test, t, std::placeholders::_1);
d2(5); // prints 5