对 bool 函数指针的参数感到困惑

Confused about parameters for bool function pointer

我正在尝试调用我的 heapify 函数,该函数应该创建一个二叉树并根据我的布尔函数参数以某种方式对它进行堆排序。

我的问题:我不确定在调用 heapify 函数时如何在 main 中传递函数指针。

我尝试将这些值与我的代码一起传递的尝试如下(我在尝试调用该函数时遇到错误:表达式必须是左值或函数指示符)

struct S {
    double x;
    int n;
    char c;
};

void heapify(S bt[], unsigned els, bool(*shouldBeBefore)(const S & a, const S & b));

int main() {
    S test[9] = { {1.1,1,'A'},{1.3,2,'B'},{1.8,3,'C'},{1.7,4,'D'},{5.1,5,'E'},{4.3,6,'F'},{3.8,7,'G'},{4.7,8,'H'},{2.7,9,'I'} };
    heapify(x, 9,&shouldBeBefore(test[0], test[1]));
    return 0;
}

bool shouldBeBefore(const S & a, const S & b) {
    if (a.x < b.x) {
        return true;
    }
    else {
        return false;
    }
}

shouldBeBefore 的声明(或整个定义)移动到调用 heapifymain 上方。但是当你调用heapify时,你只是传入了函数名。 heapify 将使用它自己的参数调用您的 shouldBeBefore 函数。

void heapify(S bt[], unsigned els, bool(*shouldBeBefore)(const S & a, const S & b));
bool shouldBeBefore(const S & a, const S & b);

int main()
{
    S test[9] = { {1.1,1,'A'},{1.3,2,'B'},{1.8,3,'C'},{1.7,4,'D'},{5.1,5,'E'},
                  {4.3,6,'F'},{3.8,7,'G'},{4.7,8,'H'},{2.7,9,'I'} };

    unsigned int length = sizeof(test)/sizeof(test[0]); // 9

    heapify(S, length, shouldBeBefore);

    return 0;
}

bool shouldBeBefore(const S & a, const S & b) 
{
    return (a.x < b.x);
}

heapify 的实现中,您可以像调用任何其他函数一样调用 shouldBeBefore

void heapify(S bt[], unsigned els, bool(*shouldBeBefore)(const S & a, const S & b))
{
    ...
        if (shouldBeBefore(S[i+1], S[i]) {
            ...
        }
    ...
}

添加到之前的回答中,我只是想澄清一个假设的关于函数指针和函数的混淆。

void heapify(S bt[], unsigned els, bool(*shouldBeBefore)(const S & a, const S & b));

int main() {
    [...]
    heapify(x, 9, shouldBeBefore(test[0], test[1]));
    [...]
}

bool shouldBeBefore(const S & a, const S & b) {
    return a.x < b.x;
}

shouldBeBefore 命名函数以及函数参数。这增加了一些混乱。 heapify 实际上允许使用任何带有签名 bool(const S&, const S&) 的函数,名字应该是这样暗示的。

对于函数指针,加上类型定义总是很方便

using Comparator = bool(*)(const S&, const S&);
// typedef bool(*Comparator)(const S&, const S&); // or by typedef

代码看起来像

void heapify(S bt[], unsigned els, Comparator comparator);

int main() {
    [...]
    heapify(x, 9, shouldBeBefore(test[0], test[1]));
    [...]
}

bool shouldBeBefore(const S & a, const S & b) {
    return a.x < b.x;
}

并且您可以像调用任何其他函数一样调用比较器。

定义函数指针有点冗长。您还可以使用 std::function,这样语法会稍微简单一些

using Comparator = std::function<bool(const S&, const S&>>;

优点是您可以使用任何可调用对象调用 heapify。