如何在 Class 中使用函数指针作为参数

How to use Function Pointer as a parameter in a Class

我正在尝试构建一个 class,它本质上是一个 futures 队列,它们都是异步处理的,最终在 main 想要获取它们的值时全部存储。我在创建将接受这些函数及其参数的函数参数时遇到问题,以便创建一个异步操作,然后将其推入期货队列。有问题的区域是调用构造函数和成员函数 add()。这是我目前所拥有的:

#include <iostream>
#include <queue>
#include <future>
#include <thread>

using namespace std;
using longInt = unsigned long long int;

//prototypes
longInt isPrime(longInt);

template <typename return_type>
class TaskQueue {
private:
    queue<future<return_type>> tasks;
public:
    //return a copy of the queue
    queue<future<return_type>> copy() const {
        return tasks;
    }


    //default constructor
    //does nothing, waits for input
    TaskQueue() {
        //do nothing
    }

    //call constructors
    //adds task to queue
    TaskQueue(return_type (*func)(), Args&& ... args) {
        tasks.push(new async(func, args));
    }

    //copy constructor
    //copies another queue to this one
    TaskQueue(const queue<future<return_type>> & in) {
        tasks = in.copy();
    }

    //setter and getter functions

    //inserts a new task into the queue
    void add(return_type(*func)(), Args&& ... args) {
        tasks.push(new aync(in, args));
    }

    //returns true if the task at the top of the queue is ready
    bool valid() {
        return tasks.front().valid();
    }

    //gets the value, if the value is not ready, waits for it to be ready
    //pops the top task after getting it
    return_type get() {
        return_type temp = tasks.top().get();

        tasks.pop();

        return temp;
    }

    //waits for the value of the top of the queue to become ready
    void wait() {
        tasks.top().wait();
    }


};

int main() {
    TaskQueue<longInt> checkPrimes;

    checkPrimes.add(isPrime, 5);

    longInt test = checkPrimes.get();

    cout << test << endl;

}

//returns the number if it is prime or 0 if it is not
longInt isPrime(longInt n) {
    if (n <= 3) {
        if (n > 1) {
            return n;
        }
        return 0;
    }

    if (n % 2 == 0 || n % 3 == 0) {
        return 0;
    }

    for (unsigned short i = 5; i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) {
            return 0;
        }
    }

    return n;
}

我认为你可以为你想要传递的函数定义一个类型,然后按照你想要的顺序应用它们。例如,下面的代码片段将定义一个 intfunc 类型,它是一个接受 int 和 return 一个 int.

的函数
typedef int (*intfunc) (int);

然后我们可以定义像

这样的函数
int sum2(int n) {
    return n + 2;
}

int mult3(int n) {
    return 3 * n;
}

并将它们赋予一个向量,

vector<intfunc> funcs;
vector<intfunc>::iterator func;
int start = 0;

funcs.push_back(sum2);
funcs.push_back(mult3);

cin >> start;
for (func = funcs.begin(); func != funcs.end(); ++func)
{
    start = (*func)(start);
}

cout << start << endl;

如果我们在该程序中输入 5,它将按预期 return 21。

可编译版本:

template <typename return_type>
class TaskQueue {
private:
    queue<future<return_type>> tasks;
public:
    //return a copy of the queue
    queue<future<return_type>> copy() const {
        return tasks;
    }


    //default constructor
    //does nothing, waits for input
    TaskQueue() {
        //do nothing
    }

    //call constructors
    //adds task to queue
    template <typename ... Args, typename ... Ts>
    TaskQueue(return_type (*func)(Ts...), Args&& ... args) {
        tasks.push(std::async(func, args...));
    }

    //copy constructor
    //copies another queue to this one
    TaskQueue(const queue<future<return_type>> & in) {
        tasks = in.copy();
    }

    //setter and getter functions

    //inserts a new task into the queue
    template <typename ... Args, typename ... Ts>
    void add(return_type(*func)(Ts...), Args&& ... args) {
        tasks.push(std::async(func, args...));
    }

    //returns true if the task at the top of the queue is ready
    bool valid() {
        return tasks.front().valid();
    }

    //gets the value, if the value is not ready, waits for it to be ready
    //pops the top task after getting it
    return_type get() {
        return_type temp = tasks.front().get();

        tasks.pop();

        return temp;
    }

    //waits for the value of the top of the queue to become ready
    void wait() {
        tasks.top().wait();
    }

};

Demo