可调用函数 C++
Callable function C++
我已经阅读了关于 SO 的各种答案,但仍然不明白在这种情况下我应该如何使对象方法可调用:
正在考虑:
Class A
{
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
one(/***/);//Should be a flag
i = 2;
}
else
{
two(/**/);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
和一个简单的主文件:
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
A myA;
A.One(pOne);
A.Two(pTwo);
int main(int argc, char** argv)
{
while(1){}
}
这是我所在的位置:
generator() 应该更新一个标志,并且 one() 和 two() 都应该轮询该标志并永远循环。
One()(two() 也)应该有一个函数指针作为参数,如果需要其他参数,pOne() 除了函数指针之外应该有相同的参数。
所以我的问题是:
1)我的理解正确吗?
2) 有没有一种干净的方法可以让 generator() 启动 one() 或 two() ? (标志、信号量、互斥量或任何标准方法)
3) 假设代码正常运行,它的行为是否符合我的预期?即打印 1 和 2?
如果重要的话,我在 ubuntu
根据您提供的任何有限信息,此代码都可以按以下方式编译:
#include <iostream>
#include <thread>
typedef void(*fptr)();
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
class A
{
public:
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
fptr func = pOne;
one(func);//Should be a flag
i = 2;
}
else
{
fptr func = pTwo;
two(func);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
func();
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
func();
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
int main()
{
A myA;
while(1)
{
}
return 0;
}
如果您希望一和二应该接受任何 type/number 个参数,则将第二个参数作为可变参数传递 template.Also 我不明白为什么您希望从主函数调用一和二作为您的参数生成器函数仅用于此目的,此生成器函数是从 class 构造函数
中分离的线程调用的
免责声明 1:与其他人一样,我将问题解释为:
-> 您需要一个事件处理程序
-> 您需要这些事件的回调方法
我认为那是因为我之前在 i2c 处理程序序列上帮助过你。
此外,还有比这更好的逻辑,它在您的存根之后提供 "rules"。
您提到您在 Ubuntu,因此您将缺少 windows 事件系统。
免责声明 2:
1- 为了避免深入,我将使用一种简单的方法来处理事件。
2- 代码未经测试且仅为逻辑提供
class Handler
{
private:
std::mutex event_one;
event_one.lock();
void stubEventGenerator(void)
{
for(;;)
{
if(!event_one.try_lock())
{
event_one.unlock();
}
sleep(15); //you had a sleep so I added one
}
}
template <typename CallbackFunction>
void One__(CallbackFunction && func)
{
while(1)
{
event_one.lock();
func();
}
}
public:
Handler()
{
std::thread H(&Handler::stubEventGenerator, this);
}
~Handler()
{
//clean threads, etc
//this should really have a quit handler
}
template <typename CallbackFunction>
void One(CallbackFunction && func) //I think you have it right, still I'm not 100% sure
{
std::thread One_thread(&Handler::One__, this, func); //same here
}
};
几点:
One() 作为调用 One__() 的线程的包装器,如果您希望它是非阻塞的。
mutex 可以是一种处理事件的简单方法,只要同一事件在之前发生时没有发生(您可以自由使用 better/more 适合您的用例的工具,或使用 boost :: 仅(如有必要)
One() 和 One__() 的原型可能是错误的,这是您的一些研究。
最后:工作原理:
std::mutex.lock() 只要它不能锁定互斥锁就会阻塞,因此 One__ 会等待,只要你的事件生成器不会解锁它。
一旦解锁 One__ 将执行您的 std::function 并等待再次引发(解锁)事件(互斥锁)。
远非完美答案,但时间不够,而且无法将其放在评论中让我post它,稍后将编辑
我已经阅读了关于 SO 的各种答案,但仍然不明白在这种情况下我应该如何使对象方法可调用:
正在考虑:
Class A
{
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
one(/***/);//Should be a flag
i = 2;
}
else
{
two(/**/);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
和一个简单的主文件:
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
A myA;
A.One(pOne);
A.Two(pTwo);
int main(int argc, char** argv)
{
while(1){}
}
这是我所在的位置:
generator() 应该更新一个标志,并且 one() 和 two() 都应该轮询该标志并永远循环。
One()(two() 也)应该有一个函数指针作为参数,如果需要其他参数,pOne() 除了函数指针之外应该有相同的参数。
所以我的问题是:
1)我的理解正确吗?
2) 有没有一种干净的方法可以让 generator() 启动 one() 或 two() ? (标志、信号量、互斥量或任何标准方法)
3) 假设代码正常运行,它的行为是否符合我的预期?即打印 1 和 2?
如果重要的话,我在 ubuntu
根据您提供的任何有限信息,此代码都可以按以下方式编译:
#include <iostream>
#include <thread>
typedef void(*fptr)();
void pOne(/**/)
{
std::cout<<"1"<<std::endl;
}
void pTwo(/**/)
{
std::cout<<"2"<<std::endl;
}
class A
{
public:
void generator(void)
{
int i = 1;
while(1)
{
if(i == 1)
{
fptr func = pOne;
one(func);//Should be a flag
i = 2;
}
else
{
fptr func = pTwo;
two(func);//Should be a flag
i = 1;
}
}
}
template <typename CallbackFunction>
void one(CallbackFunction&& func)
{
func();
}
template <typename CallbackFunction>
void two(CallbackFunction&& func)
{
func();
}
A()
{
std::thread t(&A::generator, this);
t.detach();
}
};
int main()
{
A myA;
while(1)
{
}
return 0;
}
如果您希望一和二应该接受任何 type/number 个参数,则将第二个参数作为可变参数传递 template.Also 我不明白为什么您希望从主函数调用一和二作为您的参数生成器函数仅用于此目的,此生成器函数是从 class 构造函数
中分离的线程调用的免责声明 1:与其他人一样,我将问题解释为:
-> 您需要一个事件处理程序
-> 您需要这些事件的回调方法
我认为那是因为我之前在 i2c 处理程序序列上帮助过你。
此外,还有比这更好的逻辑,它在您的存根之后提供 "rules"。
您提到您在 Ubuntu,因此您将缺少 windows 事件系统。
免责声明 2:
1- 为了避免深入,我将使用一种简单的方法来处理事件。
2- 代码未经测试且仅为逻辑提供
class Handler
{
private:
std::mutex event_one;
event_one.lock();
void stubEventGenerator(void)
{
for(;;)
{
if(!event_one.try_lock())
{
event_one.unlock();
}
sleep(15); //you had a sleep so I added one
}
}
template <typename CallbackFunction>
void One__(CallbackFunction && func)
{
while(1)
{
event_one.lock();
func();
}
}
public:
Handler()
{
std::thread H(&Handler::stubEventGenerator, this);
}
~Handler()
{
//clean threads, etc
//this should really have a quit handler
}
template <typename CallbackFunction>
void One(CallbackFunction && func) //I think you have it right, still I'm not 100% sure
{
std::thread One_thread(&Handler::One__, this, func); //same here
}
};
几点:
One() 作为调用 One__() 的线程的包装器,如果您希望它是非阻塞的。
mutex 可以是一种处理事件的简单方法,只要同一事件在之前发生时没有发生(您可以自由使用 better/more 适合您的用例的工具,或使用 boost :: 仅(如有必要)
One() 和 One__() 的原型可能是错误的,这是您的一些研究。
最后:工作原理:
std::mutex.lock() 只要它不能锁定互斥锁就会阻塞,因此 One__ 会等待,只要你的事件生成器不会解锁它。
一旦解锁 One__ 将执行您的 std::function 并等待再次引发(解锁)事件(互斥锁)。
远非完美答案,但时间不够,而且无法将其放在评论中让我post它,稍后将编辑