26

我对void operator()().

你能告诉我,例如:

class background_task
{
public:

    void operator()() const
    {
        do_something();
        do_something_else();
    }
};

background_task f;

std::thread my_thread(f);

在这里,我们为什么需要operator()()?第一个和第二个是什么意思()?实际上,我知道普通运算符的操作,但是这个运算符令人困惑。

4

4 回答 4

31

您可以重载()运算符来调用您的对象,就好像它是一个函数一样:

class A {
public:
    void operator()(int x, int y) {
        // Do something
    }
};

A x;
x(5, 3); // at this point operator () gets called

所以第一个括号总是空的:这是函数的名称:operator(),第二个括号可能有参数(如我的示例),但它们不必(如您的示例)。

因此,要在您的特定情况下调用此运算符,您将执行类似task().

于 2012-08-08T03:17:08.740 回答
24

第一个()是操作符的名称——它是()在对象上使用时调用的操作符。第二个()是参数,其中没有。

这是一个如何使用它的示例:

background_task task;
task();  // calls background_task::operator()
于 2012-08-08T03:15:06.907 回答
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()完成的内容。

于 2012-08-08T03:20:48.677 回答
1

上面提供的所有提示对于顺序程序都是正确的,我的意思是,没有线程的程序。使用线程事情会改变。首先,默认情况下 std::thread 的参数是函数和函数参数。可能你正在研究“C++ concurrency in action”一书,作者展示了一个有趣的例子:

void do_some_work(); 
thread my_thread(do_some_work); //thread receives the function address

假设这个函数:

无效do_other_job(int k);在代码正文中,您应该执行以下操作:

k=3; 
thread my_thread2(do_other_job, k); 

为了产生另一个线程。

因此,使用线程,编译器默认将 f ( in 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)。

我希望我有所帮助。

于 2015-09-08T02:53:24.220 回答