Share via


How to: Provide Work Functions to the call and transformer Classes

 

The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.

This topic illustrates several ways to provide work functions to the concurrency::call and concurrency::transformer classes.

The first example shows how to pass a lambda expression to a call object. The second example shows how to pass a function object to a call object. The third example shows how to bind a class method to a call object.

For illustration, every example in this topic uses the call class. For an example that uses the transformer class, see How to: Use transformer in a Data Pipeline.

Example

The following example shows a common way to use the call class. This example passes a lambda function to the call constructor.

// call-lambda.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Stores the result of the computation.
   single_assignment<int> result;

   // Pass a lambda function to a call object that computes the square
   // of its input and then sends the result to the message buffer.
   call<int> c([&](int n) {
      send(result, n * n);
   });

   // Send a message to the call object and print the result.
   send(c, 13);
   wcout << L"13 squared is " << receive(result) << L'.' << endl;
}

This example produces the following output.

13 squared is 169.  

Example

The following example resembles the previous one, except that it uses the call class together with a function object (functor).

// call-functor.cpp
// compile with: /EHsc
#include <agents.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Functor class that computes the square of its input.
class square
{
public:
   explicit square(ITarget<int>& target)
      : _target(target)
   {
   }

   // Function call operator for the functor class.
   void operator()(int n)
   {
      send(_target, n * n);
   }

private:
   ITarget<int>& _target;
};

int wmain()
{
   // Stores the result of the computation.
   single_assignment<int> result;

   // Pass a function object to the call constructor.
   square s(result);
   call<int> c(s);

   // Send a message to the call object and print the result.
   send(c, 13);
   wcout << L"13 squared is " << receive(result) << L'.' << endl;
}

Example

The following example resembles the previous one, except that it uses the std::bind1st and std::mem_fun functions to bind a call object to a class method.

Use this technique if you have to bind a call or transformer object to a specific class method instead of the function call operator, operator().

// call-method.cpp
// compile with: /EHsc
#include <agents.h>
#include <functional>
#include <iostream>

using namespace concurrency;
using namespace std;

// Class that computes the square of its input.
class square
{
public:
   explicit square(ITarget<int>& target)
      : _target(target)
   {
   }

   // Method that computes the square of its input.
   void square_value(int n)
   {
      send(_target, n * n);
   }

private:
   ITarget<int>& _target;
};

int wmain()
{
   // Stores the result of the computation.
   single_assignment<int> result;

   // Bind a class method to a call object.
   square s(result);
   call<int> c(bind1st(mem_fun(&square::square_value), &s));

   // Send a message to the call object and print the result.
   send(c, 13);
   wcout << L"13 squared is " << receive(result) << L'.' << endl;
}

You can also assign the result of the bind1st function to a std::function object or use the auto keyword, as shown in the following example.

   // Assign to a function object.
   function<void(int)> f1 = bind1st(mem_fun(&square::square_value), &s);
   call<int> c1(f1);

   // Alternatively, use the auto keyword to have the compiler deduce the type.
   auto f2 = bind1st(mem_fun(&square::square_value), &s);
   call<int> c2(f2);

Compiling the Code

Copy the example code and paste it in a Visual Studio project, or paste it in a file that is named call.cpp and then run the following command in a Visual Studio Command Prompt window.

cl.exe /EHsc call.cpp

See Also

Asynchronous Agents Library
Asynchronous Message Blocks
How to: Use transformer in a Data Pipeline
call Class
transformer Class