Functionality of void operator()()函数形式

时间:2022-07-03 09:11:20

 
 
class A
{
public:
	A();
	~A();
	A(int, int);
	void operator()(int a,int b) {
		cout <<"called by operator()(int a,int b):" <<a * 10<<"\t" << b * 10 << endl;
	}
private:

};

A::A()
{
}

A::~A()
{
}
A::A(int a, int b) {
	cout << "called by A::A(int a, int b):" << a << "\t" << b<<endl;
}
int main()
{
	A t(1, 2);
	t(4, 5);
	system("pause");
    return 0;
}

Functionality of void operator()()函数形式


测试时虽然构造函数和重载操作符()形似,但调用时机不同 不产生冲突


*里面有个回答

Functionality of void operator()()

前几个谈到了这个语法问题,最后一个提到了在多线程中的用处关于编译器令人头疼的语义解释, 对于形如 returnType f(para)总是解释为一个函数, 在C++ 11中新特性利用了{}等符号避免了传入的匿名类被解释为函数

http://*.com/questions/11857150/functionality-of-void-operator/11857220

I am confused about the functionality of void operator()().

Could you tell me about that, for instance:

class background_task { public: void operator()() const { do_something(); do_something_else(); } }; background_task f; std::thread my_thread(f);

Here, why we need operator()()? What is the meaning of the first and second ()? Actually, I know the operation of normal operator, but this operator is confusing.



14 down vote accepted

The first () is the name of the operator - it's the operator that is invoked when you use () on the object. The second () is for the parameters, of which there are none.

Here's an example of how you would use it:

background_task task; task(); // calls background_task::operator()
share edit
 
 
cool, more clear now. –  David Alex  Aug 8 '12 at 3:34
 
Are there any implicit calls for operator()() except this explicit call task()? –  David Alex  Aug 8 '12 at 6:22
1  
@forester2012, no you must always call it explicitly although you can use the much more awkwardtask.operator()() syntax as well. There are many standard algorithms that will call this operator internally. –  Mark Ransom  Aug 8 '12 at 13:10

You can overload the () operator to call your object as if it was a function:

class A { public: void operator()(int x, int y) { // Do something } }; A x; x(5, 3); // at this point operator () gets called

So the first parentheses are always empty: this is the name of the function: operator(), the second parentheses might have parameters (as in my example), but they don't have to (as in your example).

So to call this operator in your particular case you would do something like task().

share edit
 
 
cool, your explaination makes me clear now –  David Alex  Aug 8 '12 at 3:33
 
operator()() is only called without any parameters? Is there any other cases to run it? –  David Alex  Aug 8 '12 at 3:35
1  
@forester2012, you get to choose how many parameters there are by declaring the parameters within the second () as shown here. You may also declare different operator() functions with different parameter lists and C++ will choose the correct one based on the parameters you use when calling it. –  Mark Ransom Aug 8 '12 at 3:36 
 
Oh, I mean that if there are other implicit calls except this explicit call task()? Thank you very much. –  David Alex  Aug 8 '12 at 3:42

The first part operator() is the way to declare the function that is called when an instance of the class is invoked as a function. The second pair of parentheses would contain the actual arguments.

With a return value and arguments this might make a bit more sense:

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) );

In this context, the std::thread will internally invoke f() inside the thread, i.e. whatever is inside the body of operator() is what gets done inside that thread.

14 down vote accepted

The first () is the name of the operator - it's the operator that is invoked when you use () on the object. The second () is for the parameters, of which there are none.

Here's an example of how you would use it:

background_task task; task(); // calls background_task::operator()
share edit
 
 
cool, more clear now. –  David Alex  Aug 8 '12 at 3:34
 
Are there any implicit calls for operator()() except this explicit call task()? –  David Alex  Aug 8 '12 at 6:22
1  
@forester2012, no you must always call it explicitly although you can use the much more awkwardtask.operator()() syntax as well. There are many standard algorithms that will call this operator internally. –  Mark Ransom  Aug 8 '12 at 13:10

You can overload the () operator to call your object as if it was a function:

class A { public: void operator()(int x, int y) { // Do something } }; A x; x(5, 3); // at this point operator () gets called

So the first parentheses are always empty: this is the name of the function: operator(), the second parentheses might have parameters (as in my example), but they don't have to (as in your example).

So to call this operator in your particular case you would do something like task().

share edit
 
 
cool, your explaination makes me clear now –  David Alex  Aug 8 '12 at 3:33
 
operator()() is only called without any parameters? Is there any other cases to run it? –  David Alex  Aug 8 '12 at 3:35
1  
@forester2012, you get to choose how many parameters there are by declaring the parameters within the second () as shown here. You may also declare different operator() functions with different parameter lists and C++ will choose the correct one based on the parameters you use when calling it. –  Mark Ransom Aug 8 '12 at 3:36 
 
Oh, I mean that if there are other implicit calls except this explicit call task()? Thank you very much. –  David Alex  Aug 8 '12 at 3:42

The first part operator() is the way to declare the function that is called when an instance of the class is invoked as a function. The second pair of parentheses would contain the actual arguments.

With a return value and arguments this might make a bit more sense:

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) );

In this context, the std::thread will internally invoke f() inside the thread, i.e. whatever is inside the body of operator() is what gets done inside that thread.


All the hints that were contributed above are correct to sequential programs, I mean, programs without threads. Using threads things change. First of all, by default parameters to std::thread are functions and functions parameters. Probably you were studying the book "C++ concurrency in action", and the author shows an interesting example:

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

Suppose this function:

void do_other_job(int k); In the body of the code, you should do:

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

in order to spawn another thread.

So, using threads the compiler interprets f ( in std::thread my_thread(f);) by default as a function instead of a class. To change that you have to initiate an operator() to warn the compiler you are working with a class. An alternative code could be:

class background_task{ public: background_task(){ do_sth(); do_sth_else(); } void operator()(){} }; background_task f; thread mythread10(f);

Eventually, it's not correct, using threads, feeding the operator, so this code doesn't work:

void operator()(int x){ do_sth(); cout<<"x = "<<x<<endl; }

It happens because all the code inside the brackets are read-only, and cannot be changed during the run-time. If you aim to insert a variable in the constructor, it must be put in the thread initialization. So:

class backg{ public: backg(int i){ do_sth(i); } void operator()(){} }; int main(){ thread mythread{ backg(12) }; //using c++11 return 0; }

Will run without mistakes, and will perform the function do_sth(12) in the thread spawned.

I hope I have helped.



14 down vote accepted

The first () is the name of the operator - it's the operator that is invoked when you use () on the object. The second () is for the parameters, of which there are none.

Here's an example of how you would use it:

background_task task; task(); // calls background_task::operator()
share edit
 
    
cool, more clear now. –  David Alex  Aug 8 '12 at 3:34
    
Are there any implicit calls for operator()() except this explicit call task()? –  David Alex  Aug 8 '12 at 6:22
1  
@forester2012, no you must always call it explicitly although you can use the much more awkwardtask.operator()() syntax as well. There are many standard algorithms that will call this operator internally. –  Mark Ransom  Aug 8 '12 at 13:10

You can overload the () operator to call your object as if it was a function:

class A { public: void operator()(int x, int y) { // Do something } }; A x; x(5, 3); // at this point operator () gets called

So the first parentheses are always empty: this is the name of the function: operator(), the second parentheses might have parameters (as in my example), but they don't have to (as in your example).

So to call this operator in your particular case you would do something like task().

share edit
 
    
cool, your explaination makes me clear now –  David Alex  Aug 8 '12 at 3:33
    
operator()() is only called without any parameters? Is there any other cases to run it? –  David Alex  Aug 8 '12 at 3:35
1  
@forester2012, you get to choose how many parameters there are by declaring the parameters within the second () as shown here. You may also declare different operator() functions with different parameter lists and C++ will choose the correct one based on the parameters you use when calling it. –  Mark Ransom Aug 8 '12 at 3:36 
    
Oh, I mean that if there are other implicit calls except this explicit call task()? Thank you very much. –  David Alex  Aug 8 '12 at 3:42

The first part operator() is the way to declare the function that is called when an instance of the class is invoked as a function. The second pair of parentheses would contain the actual arguments.

With a return value and arguments this might make a bit more sense:

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) );

In this context, the std::thread will internally invoke f() inside the thread, i.e. whatever is inside the body of operator() is what gets done inside that thread.