C++函数指针返回类型

5

给出以下类(仅为标题):

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

“getCallbackFunc()”方法的正确返回类型是什么?

1
"Example::callbackFunc" 是一个函数声明,而不是一个变量。请查阅最令人困惑的解析。 - Rakete1111
你能真正地存储一个成员模板吗? - BiagioF
2个回答

5

你的问题的答案是:

bool(C::*)(Foo&)

然而,这并没有什么帮助,因为您无法在类实例中存储模板变量。
template<class C>
bool (C::*callbackFunc)(Foo&);

这不是一个合法的变量声明,你真的不能修复它。

用以下内容替换 callbackFunc

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

接着在 Example 构造函数中编写一个将成员指针转换为这样一个函数的函数。这需要从void*C*的静态转换。

Get callback func 返回:

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

这里指的是从callbackFunc隐式转换而来的类型。

使用时,需要将C*作为参数传入,并且使用Foo&


你能展示一下Example的构造函数应该长什么样吗?我还是无法让它正常工作。:( 当调用getCallbackFunc()时,C*是未知的。 - user1056903
@user 必须按照原样传递 <C>。很可能你遇到了 XY 问题,你要求解决 X 的问题,但实际上你的问题是 Y。: callbackFunc([callbackFunc](void*ptr, Foo&foo)->bool{ return (static_cast<C*>(ptr)->*callbackFunc)(foo); }){} 或类似的东西。 - Yakk - Adam Nevraumont

1
你的第一个问题是,如果不对整个类进行模板化,就无法拥有模板化的成员变量。一旦解决了这个问题,我们可以尝试使用右左规则来确定getCallbackFunc函数的返回值。我为你的构造函数添加了一个主体,因为你提供了一个初始化列表(内联构造函数)。
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);
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接