如何存储std::bind函数指针?



下面是我使用的代码

#include <functional>
#include <iostream>
#include <thread>
class Context {
private:
std::thread thread;
bool running;
void run() {
while (running) {
if (function != nullptr) {
function();
function = nullptr;
}
}
}
void (*function)();
public:
Context() : running(true) { thread = std::thread(&Context::run, this); }
~Context() {
running = false;
thread.join();
}
template <typename T, typename... Args> void call(T function, Args... args) {
this->function = std::bind(function, args...);
}
};
// Here are some test functions
void f1() { std::cout << "f1" << std::endl; }
void f2(int a) { std::cout << "f2(" << a << ")" << std::endl; }
void f3(int a, int b) {
std::cout << "f3(" << a << ", " << b << ")" << std::endl;
}
int main() {
Context context;
context.call(f1);
context.call(f2, 1);
context.call(f3, 1, 2);
return 0;
}

我希望这个类创建一个线程来运行一些函数。线程将在创建类时创建并停止当类被销毁时。为了运行一个函数,你可以用要调用的函数及其参数

f2(2);

context.call(f2, 2);

f3(3, 4);

context.call(f3, 3, 4);

然而,当我试图编译这个文件时,我得到了错误:

t.cpp: In instantiation of 'void Context::call(T, Args ...) [with T = void (*)(); Args = {}]':
t.cpp:55:15:   required from here
t.cpp:42:31: error: cannot convert 'std::_Bind_helper<false, void (*&)()>::type' to 'void (*)()' in assignment
42 |     this->function = std::bind(function, args...);
|                      ~~~~~~~~~^~~~~~~~~~~~~~~~~~~
|                               |
|                               std::_Bind_helper<false, void (*&)()>::type
t.cpp: In instantiation of 'void Context::call(T, Args ...) [with T = void (*)(int); Args = {int}]':
t.cpp:56:15:   required from here
t.cpp:42:20: error: cannot convert 'std::_Bind_helper<false, void (*&)(int), int&>::type' to 'void (*)()' in assignment
42 |     this->function = std::bind(function, args...);
|     ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.cpp: In instantiation of 'void Context::call(T, Args ...) [with T = void (*)(int, int); Args = {int, int}]':
t.cpp:57:15:   required from here
t.cpp:42:20: error: cannot convert 'std::_Bind_helper<false, void (*&)(int, int), int&, int&>::type' to 'void (*)()' in assignment

我知道这段代码不安全并且有缺陷,但我在实际实现中使用了互斥锁和安全措施。此示例只是重现错误的最小示例。

您可以使用std::function。其中,用std::function<void ()> function代替void (*function)(),如下图所示:

class Context {
private:
//other code here

std::function<void ()> function;
};

演示工作

我会选择其他方法。看一下:

#include <functional>
#include <iostream>
#include <thread>
using namespace std;
class Context
{
thread t;
public:
template<class Func, class... Args>
Context(Func func, const Args&... args) : t{ func, cref(args)... } {
}
~Context() {
if (t.joinable())
t.join();
}
};
void f1() {
cout << "f1" << endl;
}
void f2(int) {
cout << "f2" << endl;
}
void f3(int, int) {
cout << "f3" << endl;
}
int main()
{
Context c1{ f1 };
Context c2{ f2, 1 };
Context c3{ f3, 1, 2 };
}

最新更新