简体   繁体   中英

C++ function pointer return type

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 from void* 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);
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM