如何将函数回调传递给类成员

How to pass a function callback to a class member?

本文关键字:成员 回调 函数      更新时间:2023-10-16

我正在模板化一个队列类,所以我可以使用它与任何从int到任何我需要定义的结构体。

我需要传递一个比较函数给类构造函数,一个预定义的比较函数,用于整型和类似的类型,然后让客户端提供他们可能需要的任何比较函数。但我该怎么做呢?

template<typename Type>
int cmpFn(Type one, Type two)
{
    if (one < two) return -1;
    if (one > two) return 1;
    return 0;
}
template <typename Type>
class Queue
{
    public:
        Queue()
        {
            Type *list = new Type[size];
            // What do I do now?
            // How to define this constructor?
            // It must pass a comparison function
            // to a private sort method in this class.
        }
    private:
        void sortFunc(Type list, int(fn)(Type one, Type  two)=cmpFn);
};

上面的代码可能有一些错误,因为我只是从我的头脑中写下它,使我的问题更清楚。但我感兴趣的是如何在定义类时将比较函数传递给排序方法。

这是一个个人练习,我没有参加任何课程,也没有任何导师。我在谷歌上搜索了一段时间,但我找不到正确的答案……我想我没有问对谷歌先生这个问题。

注:客户端可能希望为任何类型的数据提供比较函数,例如:

struct individual
{
    string name;
    int age;
    double height;
};

我猜构造函数应该是这样的:

Queue(int (*fn)(Type, Type) = cmpFn);

但是我如何定义/实现这个呢?使用这个回调函数的不是Queue对象本身,而是它的方法:sort();

这是一个我认为你想要的工作,可编译的示例:

#include <cstddef>
#include <string>
#include <iostream>
template<typename Type>
int cmpFn(Type one, Type two)
{
    if (one < two) return -1;
    if (one > two) return 1;
    return 0;
}
template <typename Type>
class Queue
{
    public:
        // This is the typedef for your callback type
        typedef int (*callback)(Type one, Type two);
        Queue(Type *list, size_t size, callback func = cmpFn)
        {
            sortFunc(list, size, func); // works too
        }
    private:
        void sortFunc(Type *list, size_t size, callback func) {
            for (size_t i=0; i<size; i++) {
                for (size_t j=0; j<size; j++) {
                    if (i == j) continue;
                    int val = (*func)(list[i], list[j]);
                    switch (val) {
                        case 1:
                            std::cout << list[i] << " is greater than " << list[j] << "n";
                            break;
                        case -1:
                            std::cout << list[j] << " is greater than " << list[i] << "n";
                            break;
                        case 0:
                            std::cout << list[i] << " and " << list[j] << " are equaln";
                            break;
                    }
                }
            }
        }
};
int stringCmp(std::string one, std::string two) {
    if (one.size() < two.size()) return -1;
    if (one.size() > two.size()) return 1;
    return 0;
}
int main() {
    // compare ints, use generic comparison function (cmpFn)
    int myInts[2] = {1, 2};
    Queue<int> qi(myInts, 2);
    // compare strings, use our own comparison function (stringCmp)
    std::string myStrings[2] = {"foo", "bar"};
    Queue<std::string> qs(myStrings, 2, stringCmp);
    return 0;
}

编译并执行上面的程序会得到这样的输出:

2 is greater than 1
2 is greater than 1
foo and bar are equal
bar and foo are equal

基本功能:

  • Queue构造函数接受一个list数组,它的大小和一个回调函数。
  • 如果没有提供回调函数,则使用通用回调函数(cmpFn)。
  • 然后调用sortFunc,它循环通过list数组中的所有元素,并使用回调函数比较它们。

在上面的代码中,有一个intstd::string的示例。

可能像这样:

void sortFunc(Type list, int(*fn)(Type one, Type  two) = cmpFn<Type>);

最好通过const-reference传递实参,而不是通过copy传递。谁知道它们是否可以被复制呢?