2

I might be a little dense but cannot understand what below lines do?

class background_task
{
  public:
    void operator()() const
    {
      do_something();
      do_something_else();
    }
};

background_task f;
std::thread my_thread(f);
  1. I realize a thread (named my_thread) is created which calls object f of class background_task but when is the function operator() in class background_task actually called?

  2. Why is overloading of the function operator required?

  3. I understand this is C++ 101 or very basic, but I still cannot grasp it, so which books should I refer to in order to learn more about such topics of C++.

2
  • 1
    this is not about operator overloading, but about c++ functors. See this post: stackoverflow.com/a/356993/1025391 for a detailed answer to your question. Commented Apr 11, 2012 at 17:44
  • 1
    Don't worry; this is not C++ 101. An introductory C++ class certainly wouldn't cover threads, probably wouldn't cover custom function-call operators, and might not even cover writing your own classes. Commented Apr 11, 2012 at 18:30

2 Answers 2

2

This definition of operator()()

class background_task
{
public:
void operator()() const
{
  do_something();
  do_something_else();
}
};

means that you can instantiate a background_task and call it (without any arguments in this case). That makes it a "callable entity":

background_task f;
f(); // calls foo::operator ()(), i.e calls do_something() and do_something_else().

As for the thread, it needs a callable entity that takes no parameters, so passing it an instance of a background_task is fine. If background_task wasn't callable the following wouldn't compile:

background_task f;
std::thread my_thread(f);

The std::thread constructor also allows you to pass the arguments of the callable entity if it has parameters, so for example

class background_task
{
public:
void operator()(double x) const
{
  // do something with x, if you want
  do_something();
  do_something_else();
}
};

would work with

background_task f;
std::thread my_thread(f, 3.1416);

internally, the thread will do the equivalent of calling f(3.1416).

Edit: Originally I claimed there was no overloading involved. That isn't completely clear so I rephrased my answer.

Sign up to request clarification or add additional context in comments.

4 Comments

Well, although it is technically wrong, it seems to be common practice to refer to a custom operator implementation as "operator overloading". Sadly, spoken language doesn't always make sense.
@bitmask now you've got me thinking. Maybe it is overloading after all, if you consider you are overloading an operator void(void) in this case, as opposed to overloading something thathas already been defined for a particular type...
The first implicit parameter (this) always determines the function to be called. I wouldn't say void X::foo() and void Y::foo() are overloads of foo although they have the same name and differ only in the (logical) arguments. The same reasoning would apply to void operator()() const. But I'm nitpicking :)
@bitmask I guess one could argue that it is void(X*) and void(X*), i.e. overloads of operators that take a pointer to something and return void.
1
  1. The thread object std::thread(f, a, b, c) makes a copy of the object f (let's call it copy_of_f), and the entry point of the new execution context is the call copy_of_f(a, b, c) (or more verbosely, copy_of_f.operator()(a, b, c)).

  2. The object f must be a callable entity, which means that the expression f(a, b, c) must make sense.

  3. Books specifically on C++11 are still in the process of being written. Look out for Stroustrup, Meyers and others later this year. Till then, the internet is probably your best bet.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.