2012-08-08 2 views
17

void operator()()의 기능에 대해 혼란 스럽습니다.void operator()()의 기능

날은 예를 들어, 그것에 대해 말할 수 :

여기
class background_task 
{ 
public: 

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

background_task f; 

std::thread my_thread(f); 

, 왜 우리는 operator()()이 필요하십니까? 첫 번째 및 두 번째 ()의 의미는 무엇입니까? 사실, 나는 정상적인 운전자의 운전을 알고 있지만,이 운전자는 혼란 스럽다.

답변

17

첫 번째 ()은 연산자의 이름입니다.이 연산자는 객체에 ()을 사용할 때 호출됩니다. 두 번째 ()은 아무 것도없는 매개 변수 용입니다.

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

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

은 그래서 첫 번째 괄호는 : 그것은 함수 인 것처럼

background_task task; 
task(); // calls background_task::operator() 
+0

시원하고 더 분명합니다. –

+0

이 명시 적 호출 태스크()를 제외하고 operator()()에 대한 암시 적 호출이 있습니까? –

+1

@ forester2012, 아니 훨씬 더 어색한'task.operator()()'구문을 사용할 수 있지만 항상 명시 적으로 호출해야합니다. 이 연산자를 내부적으로 호출하는 많은 표준 알고리즘이 있습니다. –

21

당신은 개체를 호출 할 () 연산자를 오버로드 할 수 있습니다 여기에

당신이 그것을를 사용하는 방법의 예입니다 항상 비어 있음 : 이것은 함수의 이름입니다 : operator(), 두 번째 괄호에 매개 변수가있을 수 있지만 (예와 같이) 필요하지는 않습니다.

특정 연산자로이 연산자를 호출하면 task()과 같은 식으로 처리 할 수 ​​있습니다.

+0

멋지다, 당신의 설명은 지금 나를 분명하게합니다 –

+0

operator()()는 매개 변수없이 호출됩니까? 그것을 실행하는 다른 경우가 있습니까? –

+1

@ forester2012의 경우 여기에 표시된대로 두 번째'()'내에 매개 변수를 선언하여 몇 개의 매개 변수가 있는지 선택할 수 있습니다. 또한 다른 매개 변수 목록과 함께 다른 'operator()'함수를 선언 할 수 있으며 C++은 호출시 사용할 매개 변수에 따라 올바른 매개 변수를 선택합니다. –

6

첫 번째 부분 operator()은 클래스의 인스턴스가 함수로 호출 될 때 호출되는 함수를 선언하는 방법입니다. 두 번째 괄호 쌍에는 실제 인수가 포함됩니다. 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() : 반환 값과 인수를

하면이 좀 더 적합 할 수 있습니다 그 스레드 안에 완료.

1

위에 제공된 모든 힌트는 순차 프로그램에 맞습니다. 즉, 스레드가없는 프로그램입니다. 스레드를 사용하면 상황이 바뀝니다. 우선, 기본적으로 std :: thread에 대한 매개 변수는 함수 및 함수 매개 변수입니다. 아마 당신은이 책 "행동 C++ 동시성을"공부하였으며, 저자는 흥미로운 예를 보여줍니다

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로 f (std :: thread my_thread (f);)를 해석합니다. 이를 변경하려면 컴파일러에 경고하기 위해 연산자()를 시작해야합니다. 그러면 클래스와 작업하고 있습니다.

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) 함수를 수행합니다.

도움이 되었기를 바랍니다.

관련 문제