以下是计时器。
template <typename Duration, typename Function>
void timer(Duration const & d, Function const & f)
{
std::thread([d,f](){
std::this_thread::sleep_for(d);
f();//error here
}).detach();
}
示例myclass
定义是
class myclass {
public:
void my_functions() const {
std::cout << "my_functions called";
}
};
我称之为:
timer(std::chrono::milliseconds(10), &myclass::my_functions());
当我尝试在成员函数上调用它时,我得到error C2064: term does not evaluate to a function taking 0 arguments
答案 0 :(得分:1)
这里的问题是非静态成员函数与常规或静态函数不同。它有一个隐藏的参数,它是指向调用函数的对象的指针。
你有几种方法可以解决这个问题。首先,您可以将其设置为静态,然后将其视为正常函数,其名称的范围适用于类。如果你不能这样做那么你可以使用std::bind
创建像对象一样的函数,你可以调用函数运算符。它会像
timer(std::chrono::milliseconds(10), std::bind(&class_name::my_functions(), &class_instance));
最后,您可以像bind
那样使用lambda来打包调用。为此,语法将是
timer(std::chrono::milliseconds(10), [&class_instance](){
return class_instance.my_functions();
});
答案 1 :(得分:1)
如果没有对象实例,则无法调用非静态方法/函数(即使方法/函数中并不真正需要该对象)。
要在不需要对象的情况下实现方法调用,请声明方法static
(仍然可以在类中,但在其名称前添加static
)。
答案 2 :(得分:1)
要将非静态成员函数传递给另一个函数,您需要使用functional标题中的std::function
和std::bind
,以及实例化对象
myclass mc;
timer(std::chrono::milliseconds(1), std::bind(&myclass::my_functions, mc));
但是,您的代码可能无法正常工作,因为要查看消息,您必须等待线程进行调用。这是一个工作的简单例子
#include <thread>
#include <iostream>
#include <functional>
#include <chrono>
template <typename Duration, typename Function>
void timer(Duration const & d, Function const & f)
{
std::thread([d, f](){
std::this_thread::sleep_for(d);
f();//error here
}).detach();
}
class myclass{
public:
void my_functions() const {
std::cout << "aaa";
}
};
int main(){
myclass mc;
timer(std::chrono::milliseconds(1), std::bind(&myclass::my_functions, mc));
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
正确的方法当然是等待线程完成。
此外,如果您的成员函数的唯一目的是输出一条消息,您可以将其设置为静态且不受约束。
答案 3 :(得分:1)
如果您可以收取timer()
功能的参数列表,那么这也可以。
#include <iostream>
#include <chrono>
#include <thread>
template <typename Duration, typename Function, typename Class>
void timer(Duration const & d, Function const & f,Class const& o)
{
std::thread([d,f,o](){
std::this_thread::sleep_for(d);
f(o);//error here
}).detach();
}
class Foo{
public:
Foo() {}
void func() const {
std::cout<<__func__<<":"<<__LINE__<<std::endl;};
}
int main(){
std::function<void(const Foo&)> foo_func = &Foo::func;
const Foo foo;
timer(std::chrono::seconds(2),foo_func,foo);
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}