我对void operator()()
的功能感到困惑。
你能否告诉我这个问题,例如:
class background_task
{
public:
void operator()() const
{
do_something();
do_something_else();
}
};
background_task f;
std::thread my_thread(f);
在这里,为什么我们需要operator()()
?第一个和第二个()
的含义是什么?实际上,我知道普通算子的操作,但这个操作符令人困惑。
答案 0 :(得分:25)
您可以重载()
运算符以将对象称为函数:
class A {
public:
void operator()(int x, int y) {
// Do something
}
};
A x;
x(5, 3); // at this point operator () gets called
所以第一个括号总是空的:这是函数的名称:operator()
,第二个括号可能有参数(如我的例子中所示),但它们没有(如你的例子中) )。
因此,要在特定情况下调用此运算符,您可以执行task()
。
答案 1 :(得分:20)
第一个()
是运算符的名称 - 它是在对象上使用()
时调用的运算符。第二个()
用于参数,其中没有参数。
以下是您将如何使用它的示例:
background_task task;
task(); // calls background_task::operator()
答案 2 :(得分:7)
第一部分operator()
是声明在作为函数调用类的实例时调用的函数的方法。第二对括号将包含实际参数。
使用返回值和参数,这可能会更有意义:
class Adder{
public:
int operator()(int a, int b){
//operator() -- this is the "name" of the operator
// in this case, it takes two integer arguments.
return a+b;
}
};
Adder a;
assert( 5==a(2,3) );
在这种情况下,std::thread
将在线程内部调用f()
,即operator()
体内的任何内容都是在该线程内完成的。
答案 3 :(得分:1)
上面提供的所有提示对顺序程序都是正确的,我的意思是,没有线程的程序。使用线程的东西会改变 首先,默认情况下std :: thread的参数是函数和函数参数。可能你正在研究“C ++并发行动”这本书,作者展示了一个有趣的例子:
void do_some_work();
thread my_thread(do_some_work); //thread receives the function address
假设这个功能:
void do_other_job(int k); 在代码正文中,你应该这样做:
k=3;
thread my_thread2(do_other_job, k);
为了产生另一个线程。
因此,使用线程,编译器默认将f(在 std :: thread my_thread(f); 中)解释为函数而不是类。要更改它,您必须启动operator()来警告编译器您正在使用类。 替代代码可以是:
class background_task{
public:
background_task(){
do_sth();
do_sth_else();
}
void operator()(){}
};
background_task f;
thread mythread10(f);
最终,这是不正确的,使用线程,为操作员提供信息,因此此代码不起作用:
void operator()(int x){
do_sth();
cout<<"x = "<<x<<endl;
}
这是因为括号内的所有代码都是只读的,并且在运行时无法更改。如果您的目标是在构造函数中插入变量,则必须将其放入线程初始化中。所以:
class backg{
public:
backg(int i){
do_sth(i);
}
void operator()(){}
};
int main(){
thread mythread{ backg(12) }; //using c++11
return 0;
}
将运行无错误,并将在生成的线程中执行函数do_sth(12)。
我希望我有所帮助。