26

I'm currently studying boost threads. And I came across that the thread class has a constructor that accepts callable objects. What are callable objects?

class CallableClass
{
private:
    // Number of iterations
    int m_iterations;

public:

    // Default constructor
    CallableClass()
    {
        m_iterations=10;
    }

    // Constructor with number of iterations
    CallableClass(int iterations)
    {
        m_iterations=iterations;
    }

    // Copy constructor
    CallableClass(const CallableClass& source)
    {
        m_iterations=source.m_iterations;
    }

    // Destructor
    ~CallableClass()
    {
    }

    // Assignment operator
    CallableClass& operator = (const CallableClass& source)
    {
        m_iterations=source.m_iterations;
        return *this;
    }

    // Static function called by thread
    static void StaticFunction()
    {
        for (int i=0; i < 10; i++)  // Hard-coded upper limit
        {
            cout<<i<<"Do something in parallel (Static function)."<<endl;
            boost::this_thread::yield(); // 'yield' discussed in section 18.6
        }
    }

    // Operator() called by the thread
    void operator () ()
    {
        for (int i=0; i<m_iterations; i++)
        {
            cout<<i<<" - Do something in parallel (operator() )."<<endl;
            boost::this_thread::yield(); // 'yield' discussed in section 18.6
        }
    }

};

How does this become a callable object? Is it because of the operator overloaded or the constructor or something else?

3
  • 2
    It's because operator(), yes. See here. In addition "callable objects" in this contexts are also, functions, function pointers and lambda functions.
    – jrok
    Commented Oct 9, 2013 at 17:11
  • 1
    It's the overloaded operator(). It lets you call an instance of that class like a function. They're called functors, function objects, callable objects, etc.
    – Simple
    Commented Oct 9, 2013 at 17:11
  • 2
    You should tag (and name) this question with boost. Boost is not a standard C++ library, so the very large boost community here might be able to pick this up faster if you tagged and named it properly.
    – user401142
    Commented Oct 9, 2013 at 17:34

7 Answers 7

29

A callable object is something that can be called like a function, with the syntax object() or object(args); that is, a function pointer, or an object of a class type that overloads operator().

The overload of operator() in your class makes it callable.

8

There are two steps here. In the C++ Standard, a "function object" is an object that can appear on the left-hand side of a parenthesized argument list, i.e, a pointer to function or an object whose type has one or more operator()s. The term "callable object" is broader: it also includes pointers to members (which can't be called with the normal function call syntax). Callable objects are the things that can be passed to std::bind etc. See 20.8.1 [func.def] and 20.8[function.objects]/1.

5

A callable object is an object instance from a class with operator() overloaded:

struct Functor {
    ret_t operator()();
    // ...
}

Functor func;  // func is a callable object

or a dereferenced-function pointer:

ret_t func() {
   // ...
}

func;  // func converts to a callable object
4
  • "A function is not an object... (§1.8/1)"
    – masoud
    Commented Oct 9, 2013 at 17:21
  • 1
    @MM.: Which is why the answer says "a function pointer", not "a function". Perhaps the code comment could be more precise, e.g. "func converts to a callable object". Commented Oct 9, 2013 at 17:23
  • @MikeSeymour: Indeed function pointer is an object, but it's not callable. In fact, a dereferenced-function-pointer is callable, IMO. Am I right?
    – masoud
    Commented Oct 9, 2013 at 17:32
  • @MM. - a function pointer is callable: f(3). Don't get into the details of whether a function pointer has to be dereferenced. (*******f)(3), where f is a function pointer, is valid. Commented Oct 9, 2013 at 17:42
5

An object which has at least an overloaded operator() is a callable object, and that operator plus its object can be invoked like function invoking:

CallableClass obj;
obj();
4
  • I think that "callable object" has a broader definition than just this, but I can't find a reference. To be sure, a class with an operator() is a callable object -- I'm just not certian the reverse is true. Commented Oct 9, 2013 at 17:23
  • @JohnDibling: Yes, and I said "An object ... is a callable object" not in the reverse.
    – masoud
    Commented Oct 9, 2013 at 17:29
  • @JohnDibling - you're right: "callable object" includes pointer to member. Things that can be called with a parenthesized argument list are function objects. Commented Oct 9, 2013 at 18:13
  • 1
    @JohnDibling effective modern c++,1st edition,five print or standard c++ library,second edition,3rd print
    – Tu Xiaomi
    Commented Jan 8, 2016 at 1:55
3

In C++11, a callable element can be either:

  • A function pointer,
  • A member function pointer, (it is different from the previous one, check here)
  • An object of a functor class (a class wherein its operator() is implemented),
  • Anonymous functions (Lambdas),
  • Or any of the mentioned elements wrapped in a std::function object.

This means that you can use each of the mentioned callable elements to launch a std::thread. Take a look at the following sample code:

std::vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

int func()
{
   return std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
}

class A
{
public:
   int mem_func() 
   { 
      return std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
   }
};

class B
{
public:
   int operator()()
   {
      return std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
   }
};

auto lambda = []() { return std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>()); };


void main()
{
   A a;
   B b;

   std::function<int()> f1 = &func;
   std::function<int()> f2 = std::bind(&A::mem_func, &a);
   std::function<int()> f3 = std::bind(&B::operator(), &b);
   std::function<int()> f4 = lambda;

   std::thread t1 = std::thread(func);
   std::thread t2 = std::thread(&A::mem_func, a);
   std::thread t3 = std::thread(&B::operator(), b);
   std::thread t4 = std::thread(lambda);

   std::thread t5 = std::thread(f1);
   std::thread t6 = std::thread(f2);
   std::thread t7 = std::thread(f3);
   std::thread t8 = std::thread(f4);

   t1.join();
   t2.join();
   t3.join();
   t4.join();
   t5.join();
   t6.join();
   t7.join();
   t8.join();
}
3

Since C++17, a Callable object is defined by the standard; see https://en.cppreference.com/w/cpp/named_req/Callable for details.

1
  • The link is broken :(
    – TonySalimi
    Commented Mar 11, 2019 at 17:08
1

Function object add member function pointers yields what are known as callable objects. When we in c++ 98/03,we use the class override the operator() as function.In general, we call that class function.It has the advantage of storing state of the function and other function can't.So it is the most important concept.And border, we call this style class function and other c style function and pointer to c style function "function object". The callable object is just "callable" object. It include function object and member function pointers.

Not the answer you're looking for? Browse other questions tagged or ask your own question.