简体   繁体   English

C ++函数指针返回类型

[英]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() ? 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 callbackFunc替换callbackFunc

std::function< bool(void*, Foo&) > callbackFunc;

Then in Example ctor write a function that converts the member ptr into such a function. 然后在Example ctor中编写一个将成员ptr转换为这样一个函数的函数。 It involves a static cast from void* to C* . 它涉及从void*C*的静态转换。

Get callback func returns: 获取回调函数返回:

std::function< bool(C*, Foo&) >

which is implicitly-converible-to from callbackFunc . 它是来自callbackFunc隐式转换。

You use it by passing C* in and the Foo& . 你通过传递C*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 . 一旦修复,我们可以尝试使用右左规则找出getCallbackFunc函数的返回值。 I added a body to your constructor because you provided an init-list (inline constructor). 我为你的构造函数添加了一个body,因为你提供了一个init-list(内联构造函数)。

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 : 使用using声明创建类型别名可以稍微简化一下:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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