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

时间:2011-11-14 18:25:08

标签: c++ templates function callback pass-by-reference

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

我需要将比较函数传递给类构造函数,这是一个用于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);
};

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

这是一项个人练习,我没有参加任何课程,也没有任何导师。我一直在谷歌上搜索一段时间,但我无法得到正确的答案......我想我并没有向谷歌先生提出正确的问题。

P.S。 客户可能希望为任何类型的数据提供比较函数,例如:

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

我猜构造函数必须是这样的:

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

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

2 个答案:

答案 0 :(得分:2)

这是我认为你想要的一个可用的,可编辑的例子:

#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 equal\n";
                            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的示例。

答案 1 :(得分:0)

也许是这样的:

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

可能最好通过const-reference而不是copy来传递参数。谁知道他们是否可以复制?