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

发布于 2024-12-15 14:47:31 字数 1143 浏览 3 评论 0原文

我正在模板化一个队列类,以便我可以将它与从整数到我需要定义的任何结构的任何内容一起使用。

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

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();

I'm templatizing a queue class so I can use it with anything from ints to whatever structs I need to define.

I need to pass a comparison function to the class constructor, a predefined comparison function for ints and alike then leave it up to the client to provide any comparison functions they may want. But how do I do this?

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);
};

There's probably some mistakes in the above code since I just wrote it down from the top of my head to make my question more clear. But all I'm interested in is how to pass a comparison function to a sort method when defining a class.

This is a personal exercise, I'm not enrolled in any course nor have I access to any tutors. I've been googling this for a while now, but I couldn't come up with the right answer... I guess I wasn't asking the right question to Mr. Google.

P.S.
The client may want to provide comparison functions for any sort of data, like:

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

I guess that the constructor has to be like this:

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

But how do I define/implement this? It's not a Queue object itself who will use this callback function, but its method: sort();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嗳卜坏 2024-12-22 14:47:31

这是我认为您想要的一个有效的、可编译的示例:

#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 的示例。

Here's a working, compilable example of what I think you want:

#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;
}

Compiling and executing the program above should give you this output:

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

Basically what it does:

  • The Queue constructor accepts a list array, its size and a callback function.
  • If the callback function is not provided, it uses the generic one (cmpFn).
  • It then calls sortFunc which loops though all the elements in the list array and compare them using the callback function.

In the code above, you have an example with int and std::string.

鸠魁 2024-12-22 14:47:31

也许是这样的:

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

可能最好通过常量引用而不是通过复制来传递参数。谁知道它们是否可以复制?

Maybe like this:

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

Probably best to pass the arguments by const-reference rather than by copy. Who knows if they're even going to be copyable?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文