C ++成员函数指针定义是怎样的?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (25)

我在考虑这个代码:

#include <iostream>
#include <functional>

struct B {
    template <class C, class M, class T>
    void call1(C (M::*member)(), T *instance) {
        std::function<void()> fp = std::bind(member, instance);
        fp();
    }

    template <class C, class M, class T>
    void call2(C (M::*member), T *instance) {
        std::function<void()> fp = std::bind(member, instance);
        fp();
    }

    void foo() {
        call1(&B::func, this); // works
        call2(&B::func, this); // works

        call1(&B::func2, this); // Error: no matching member function for call to 'call2'
        call2(&B::func2, this); // works
    }

    void func() {
        std::cout << "func\n";
    }

    void func2() const volatile {
        std::cout << "func2\n";
    }
};

int main() {
    B{}.foo();
}

指定一个像这样的函数成员指针C (M::*member)()和像这样的区别是什么?

提问于
用户回答回答于

让我们简化为只考虑以下两者之间的区别:

template <class C, class M> void f(C (M::*member)());
template <class C, class M> void g(C (M::*member));

让我们来看一个重载函数的例子,以及它如何得到不同的推导:

struct X {
    void bar() { }
    void bar(int ) { }
};

当我们这样做时:

f(&X::bar);

即使&X::bar是一个重载的名称,只有一个实际匹配C (M::*)()。那个有M == XC == voidbar采取int匹配模板类型的重载根本没有办法。所以这是传递重载名称的可接受用法之一。

但是,当我们这样做时:

g(&X::bar);

现在回到你的例子:

call1(&B::func2, this); // Error: no matching member function for call to 'call2'
call2(&B::func2, this); // works

扫码关注云+社区

领取腾讯云代金券