Procedura: fornire funzioni lavoro alle classi call e transformer

In questo argomento vengono illustrati vari modi per fornire funzioni lavoro alle classi Concurrency::call e Concurrency::transformer.

Nel primo esempio viene illustrato come passare un'espressione lambda a un oggetto call. Nel secondo esempio viene illustrato come passare un oggetto funzione a un oggetto call. Nel terzo esempio viene illustrato come associare un metodo della classe a un oggetto call.

A titolo esemplificativo, ogni esempio in questo argomento utilizza la classe call. Per un esempio che utilizza la classe transformer, vedere Procedura: Utilizzare la classe transformer in una pipeline di dati.

Esempio

Nell'esempio seguente viene illustrato un utilizzo comune della classe call. In questo esempio viene passata una funzione lambda al costruttore call.

// 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;
}

Questo esempio produce l'output che segue.

13 squared is 169.

L'esempio seguente è simile al precedente, ad eccezione del fatto che la classe call viene utilizzata insieme a un oggetto funzione (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;
}

L'esempio seguente è simile al precedente, con l'unica eccezione che utilizza le funzioni std::bind1st e std::mem_fun per associare un oggetto call a un metodo della classe.

Utilizzare questa tecnica se è necessario associare un oggetto call o transformer a un metodo della classe specifico anziché l'operatore della chiamata di funzione, 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;
}

È inoltre possibile assegnare il risultato della funzione bind1st a un oggetto std::function oppure utilizzare la parola chiave auto, come mostrato nell'esempio seguente.

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

Compilazione del codice

Copiare il codice di esempio e incollarlo in un progetto di Visual Studio o incollarlo in un file denominato call.cpp, quindi eseguire il comando seguente in una finestra del prompt dei comandi di Visual Studio 2010.

cl.exe /EHsc call.cpp

Vedere anche

Attività

Procedura: Utilizzare la classe transformer in una pipeline di dati

Riferimenti

Classe call

Classe transformer

Concetti

Libreria di agenti asincroni

Blocchi dei messaggi asincroni