Given is the following class (just the header):
class Example {
public:
template<class C>
Example(bool(C::*callbackFunc)(Foo&) = nullptr) : callbackFunc(callbackFunc);
template<class C>
??? getCallbackFunc() const {
return callbackFunc;
}
private:
// store the func ptr
template<class C>
bool (C::*callbackFunc)(Foo&);
};
What is the correct return type of the getter getCallbackFunc()
?
The answer to your question is:
bool(C::*)(Foo&)
However, this won't help you much, as you cannot store a template variable in a class instance:
template<class C>
bool (C::*callbackFunc)(Foo&);
That is not a legal variable declaration, and you really cannot fix it.
Replace callbackFunc
with
std::function< bool(void*, Foo&) > callbackFunc;
Then in Example
ctor write a function that converts the member ptr into such a function. It involves a static cast fromvoid*
to C*
.
Get callback func returns:
std::function< bool(C*, Foo&) >
which is implicitly-converible-to from callbackFunc
.
You use it by passing C*
in and the Foo&
.
Your first problem is you can't have templated member variables without temlating the entire class. Once that's fixed we can try to figure out the return value of your getCallbackFunc
function using The Right Left Rule. I added a body to your constructor because you provided an init-list (inline constructor).
struct Foo {};
// need to template the whole class to
// template member variables
template<class C>
class Example {
public:
Example(bool(C::*callbackFunc)(Foo&) = nullptr)
: callbackFunc(callbackFunc) {} // init list means this needs a body
// use the right-left-rule
bool (C::*getCallbackFunc())(Foo&) {
return callbackFunc;
}
private:
// store the func ptr
bool (C::*callbackFunc)(Foo&);
};
class CallbackClass
{
public:
bool call_me_back(Foo&) { std::cout << "Glad you called" << '\n'; return true; }
};
int main()
{
Example<CallbackClass> eg(&CallbackClass::call_me_back);
CallbackClass cbc; // instantiate something to call
Foo foo; // need a foo for parameter
// get fn pointer, dereference it and call it with cbc object
bool return_value = (cbc.*eg.getCallbackFunc())(foo);
}
This can all be simplified somewhat using the using
declaration to create a type alias:
struct Foo {};
// create a templated type alias
template<typename C>
using CallbackType = bool(C::*)(Foo&);
// need to template the whole class to
// template member variables
template<class C>
class Example {
public:
Example(CallbackType<C> callbackFunc = nullptr)
: callbackFunc(callbackFunc) {} // init list means this needs a body
// using the type alias
CallbackType<C> getCallbackFunc() {
return callbackFunc;
}
private:
// store the func ptr
CallbackType<C> callbackFunc;
};
class CallbackClass
{
public:
bool call_me_back(Foo&) { std::cout << "Glad you called" << '\n'; return true; }
};
int main()
{
Example<CallbackClass> eg(&CallbackClass::call_me_back);
CallbackClass cbc; // instantiate something to call
Foo foo; // need a foo for parameter
// get fn pointer
CallbackType<CallbackClass> cb = eg.getCallbackFunc();
// dereference it and call it with cbc object
bool return_value = (cbc.*cb)(foo);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With