如何将另一个类的函数作为参数传递?

时间:2019-03-29 08:03:28

标签: c++

我想将另一个类的函数作为参数传递给当前类。我正在尝试做这样的事情(我简化了代码,所以您仍然可以理解):

B class:

bool B::myCmpFunc(int a, int b) {
    return a > b;
}

vector<int> B::sort(bool (*cmp)(int a, int b)) {
    vector<int> elems = getElems();
    for (int i = 0; i < elems.size() - 1; i++) {
        for (int j = i + 1; j < elems.size(); j++) {
            if ((*cmp)(elems[i], elems[j])) {
                int aux = elems[i];
                elems[i] = elems[j];
                elems[j] = aux;
            }
        }
    }
    return elems;
}

然后我尝试从A class调用此排序函数:

B b;
auto sortedElems = b.sort(&b.myCmpFunc);

问题是,当我尝试通过&b.myCmpFunc 作为A class中的参数时出现此错误:

  

错误C2276'&':对绑定成员函数的非法操作   表达

我还尝试了另一种方法,例如将函数传递为b.myCmpFunctB::myCmpFunc&B::myCmpFunc,但是仍然出现错误。

2 个答案:

答案 0 :(得分:1)

您将指向普通函数的指针和指向成员函数的指针混合在一起。这些是不同的概念,在某些时候值得理解。您可以做的是使比较函数成为auto sortedElems = b.sort(&B::myCmpFunc); ,然后像这样传递一个指针:

myCmpFunc

否则,您可以将auto sortedElems = b.sort(&myFreeCmpFunc); 作为 free 函数实现,即不绑定到类。然后将其传递为

myCmpFunc

在任何情况下,拥有不依赖于其对象状态的成员函数std::greater<>{}都没有多大意义。使其成为自由函数可以增加封装,并使比较函数可重用(除了您也可以使用T<A>函数对象的事实。

答案 1 :(得分:1)

当您拥有class函数(类中的非静态函数)时,您需要传递this /类的实例,以便编译器可以传递this /函数调用时对象的实例。

您可以:

  1. 执行您的功能static。类内的static函数不使用this /对象实例,因此它们的指针是正常的。

static bool B::myCmpFunc(int a, int b) {}
b.sort(&b.myCmpFunc);
// or
b.sort(&B::myCmpFunc);
  1. 您可以重构函数以使用std::function并使用thisstd::bind与对象指针绑定。

vector<int> B::sort(std::function<bool(int a, int b)> cmp) {
        ... no changes ...
}
b.sort(std::bind(&B::myCmpFunc, &b, std::placeholders::_1, std::placeholders::_2));
  1. 重构您的函数以仅使用B类函数。

vector<int> B::sort(bool (B::*cmp)(int a, int b)) {
       ...
       (this->*cmp)(...);
       ...
}
b.sort(&B::myCmpFunc);
  1. 使用lambda。

b.sort([](int a, int b) -> bool { return a < b; });
// really or
b.sort([&b](int a, int b) -> bool { return b.myCmpFunc(a, b); });
  1. 还有更多(例如模板)。

由于成员函数B::myCmpFunc似乎并没有使用this指针或对象成员,因此我将其声明为static