2014-09-02 30 views
6

'u çalıştırın. Fonksiyon konteynırı olarak vektör/deque yapmak istiyorum.Fonksiyonları vektöre yerleştirin ve

Bu muhafaza, farklı argümanlarla farklı işlevler almalıdır.

Örnek fonksiyonları:

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

Ve örnek kod std için argümanlar :: vector/std :: deque ile bu fonksiyonları koydu ve yürütmek nasıl gösterebilirim?

Sanırım std :: function ve std :: bind kullanmalıyım ama farklı işlevlerle farklı işlevleri nasıl destekleyeceğimi bilmiyorum. argümanlar ile

-> (program_data den functionfooexam denir) benim işlevleri argümanlar kullanarak bazı eylemleri yapmak. Örneğin

:

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

Ve şimdi std::vector // deque için bu işlevleri koymak ve ben fonksiyonu ile koymak argümanlarla yürütmek istiyorum: Normalde ben bu işlevi gerçekleştirmek. yani, (i (pseudocode vektörüne yukarıdaki işlevini koymak ve kullanımı halinde) vector[0].run(); sonra programım çalışma fonksiyonu program_data::getInstance().function(int,std::string);)

+1

"argümanlar ile" - yani çağrıldığında, belirtilen argümanlarla işlevi çağırmakla aynı etkiye sahip olan bir şey oluşturmak istediğiniz anlamına gelir? –

+1

Lambda ifadeleri mi arıyorsunuz? https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 – MrTux

+1

Argümanlarınızın değerleri enque zamanında biliniyor mu? İşlevlerinizin dönüş tipi daima aynı mıdır? – Christophe

cevap

11

Kesinlikle std::vector<std::function<void()>> kullanımı - yani, herhangi bir nesneyi tutmak tip-silinmiş işlev kaplar bir vektörü çağrılabilir bağımsız değişkenler:

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](); 

Burada vektörü kapısız bir lambda ile dolduruyorum; Ayrıca lambdaları yakalama, bağlama ifadeleri (std::bind) ve diğer değiştirilebilir nesnelere de kullanabilirsiniz.

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

için göstermenizi ve örnek Could 'std :: string tmp;?' 'Program_data :: getInstance(). function (10, tmp); 'td, 'std :: string &tmp;' argümanıdır. 'Elbette değişken erişilebilir olduğunda –

2

Ben std::function kullanarak öneririm: Bir yakalama ile lambda kullanırsanız

, bu yakalanan değişkenleri ya değeriyle kaydedilmesini sağlar veya callables toplama olduğunu içeren bir ömrü olması gerekir ve lambda expressions:

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

Bu vektör 'fonksiyonları' bir işlev ekler. Bu, functions[0]() numaralı telefonu arayarak, lambda ifadesini çağıracaktır, bu daha sonra işlevinizi 123, 456 ve argümanlar olarak "str" ​​ile çağırır.

1

std::function/std::bind'u kullanabilirsiniz. Bu nedenle, öncelikle, bu fonksiyonlara arayan taraflardan neyi ileteceğinize, yani fonksiyon imzasını belirlemeye ihtiyacınız vardır. İlke, sanal işlevlerle aynıdır. Yani, örneğin, bir sıra numarası geçmesi (sırası fonksiyonları denir) ve hiçbir şey geri dönmek istiyorum: Bu yöntemin

#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); 
    } 
} 

Fayda, bu artırma ile ++ 11 derleyici c öncesi için kullanılabilir.