26

の機能について混乱していますvoid operator()()

たとえば、それについて教えていただけますか。

class background_task
{
public:

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

background_task f;

std::thread my_thread(f);

ここで、なぜ必要なのoperator()()ですか?1番目と2番目の意味は何()ですか? 実は普通のオペレーターの操作は知っているのですが、このオペレーターはややこしいです。

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()、2番目の括弧は(私の例のように)パラメーターを持っている可能性がありますが、(あなたの例のように)そうする必要はありません。

したがって、特定の場合にこの演算子を呼び出すには、のようなことを行いますtask()

于 2012-08-08T03:17:08.740 に答える
24

1つ目()は演算子の名前です()。これは、オブジェクトで使用するときに呼び出される演算子です。2つ目()はパラメーター用ですが、パラメーターはありません。

使用方法の例を次に示します。

background_task task;
task();  // calls background_task::operator()
于 2012-08-08T03:15:06.907 に答える
7

最初の部分operator()は、クラスのインスタンスが関数として呼び出されたときに呼び出される関数を宣言する方法です。括弧の2番目のペアには、実際の引数が含まれます。

戻り値と引数を使用すると、これはもう少し意味があるかもしれません。

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

この関数を仮定します:

void 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 に答える