2014-09-02 11 views
6

Voglio creare un vettore/deque come contenitore di funzioni.Metti le funzioni in vettoriale ed esegui

Questo contenitore deve assumere funzioni diverse con argomenti diversi.

funzioni Esempio:

program_data::getInstance().function(int,std::string); 
program_data::getInstance().foo(int); 
program_data::getInstance().exam(int,std::string,double); 

E potrebbe mostrare esempio di codice come mettere queste funzioni con argomenti per std :: vector/std :: deque e eseguire?

Penso che dovrei usare std :: function e std :: bind ma non so come supportare diverse funzioni con dimensioni di args differenti.

Con argomenti -> le mie funzioni (chiamate functionfooexam da program_data) fare alcune azioni utilizzando argomenti.

Ad esempio: normalmente eseguo questa funzione:

program_data::getInstance().function(10,"halo");

e ora voglio mettere queste funzioni per std::vector // deque ed eseguire con argomenti che ho messo con la funzione. Per esempio (se metto funzione sopra per vettore e utilizzare (pseudocodice) vector[0].run(); poi mio programma funzione run program_data::getInstance().function(int,std::string);)

+1

"con argomenti" - significa che si desidera creare qualcosa che, quando chiamato, ha lo stesso effetto di chiamare la funzione con gli argomenti specificati? –

+1

Forse stai cercando espressioni lambda? https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 – MrTux

+1

I valori dei tuoi argomenti sono noti all'ora di enque? Il tipo di ritorno delle tue funzioni è sempre lo stesso? – Christophe

risposta

11

Assolutamente, utilizzare std::vector<std::function<void()>> - cioè, un vettore di contenitori funzionali di tipo-cancellati che può contenere qualsiasi oggetto che è richiamabile senza argomenti:

std::vector<std::function<void()>> vector; 

// populate the vector 
vector.push_back([]{ program_data::getInstance().function(10,"halo"); }); 

// execute items in the vector 
vector[0](); 

Qui sto popolando il vettore con un lambda captureless; puoi anche utilizzare lambda con catture, espressioni di collegamento (std::bind) e altri oggetti chiamabili.

Se si utilizza un lambda con una cattura, è necessario garantire che le variabili catturati o sono catturati da valore o hanno una vita che contiene quella della collezione di oggetti chiamabili:

std::string tmp; 
vector.push_back([&tmp]{ program_data::getInstance().something(tmp); }); 
+0

Potrebbe mostrare e ad esempio quando la variabile viene inviato con riferimento 'std :: string tmp;??' 'Program_data :: getInstance(). function (10, tmp); 'dove tmp è argomento di' std :: string &tmp; 'Naturalmente quando la variabile è disponibile per l'accesso –

2

Io suggerirei di usare std::function e lambda expressions:

std::vector<std::function<void()>> functions; 
functions.push_back([](){ program_data::getInstance().function(123, 456, "str"); }); 

Questo aggiunge una funzione nei tuoi 'funzioni' vettoriali. Chiamando functions[0](), si chiamerà l'espressione lambda che chiama la propria funzione con 123, 456 e "str" ​​come argomenti.

1

È possibile utilizzare std::function/std::bind. Quindi, prima di tutto è necessario determinare che cosa passerete a quelle funzioni dal lato del chiamante, cioè determinare la firma della funzione. Il principio è lo stesso delle funzioni virtuali. Così, ad esempio, si desidera passare un numero di sequenza (in cui le funzioni di ordine vengono chiamate) e restituire nulla:

#include <vector> 
#include <functional> 

typedef std::function< void(int) > Function; 
typedef std::vector<Function> Functions; 


void func1(int seq, const std::string &str); 
void func2(const std::string &str); 
void func3(int seq); 

void run() 
{ 
    Functions functions; 
    // populate functions 
    functions.push_back(std::bind(func1, std::placeholders::_1, "foobar")); 
    functions.push_back(std::bind(func2, "foobar too")); 
    functions.push_back(func3); // you can use std::bind here as well, just to show it can be omitted if function signature matches 

    // call them 
    for(size_t i = 0; i < functions.size(); ++i) { 
     functions[i](i); 
    } 
} 

vantaggio di questo metodo, esso può essere utilizzato per il pre C++ 11 compilatore con boost.

Problemi correlati