2015-04-28 51 views
10

thread yapıcısı gibi çalışan bir işlev çağrısı uygulamak isterim. ÖrneğinC++ evrensel işlev çağrısı

std::thread second (bar,0); 

tek argüman 0 ile bar çağıran bir iş parçacığı başlayacaktır. Ben de aynı şeyi yapmak isterdim ama nasıl olduğunu bilmiyorum. Verilen örnek için

:

void myFunc(int a){ 
    cout << a << endl; 
} 

ben gibi olacaktır:

int main() { 
    caller(myFunc,12); 
} 

parametre 12 ile myFunc arayın.

+6

'std :: function' ve' std :: bind' türlerini belirtmeniz gerekir. –

+0

sinyal/yuva göz önünde bulundurur mu? – user3528438

+1

C++ 17 için, tam olarak bunu yapan ['std :: invoke()'] (http://en.cppreference.com/w/cpp/utility/functional/invoke) olacaktır. – DanielKO

cevap

21

std::bind, thread yapıcısının yaptığı gibi, herhangi bir uçbirim nesnesinden, rastgele bir parametre kümesine sahip bir çağrılabilir nesneyi yapar. Dolayısıyla, sadece onu çağıran bir işlev olduğunu sarın:

template <typename... Args> 
auto caller(Args &&... args) { 
    return std::bind(std::forward<Args>(args)...)(); 
} 

Not auto döndürme türü C++ 14 veya üstü gerektirir. C++ 11 için, void değerini döndürmeniz veya

auto caller(Args &&... args) 
    -> decltype(std::bind(std::forward<Args>(args)...)()) 
+0

Bir nesneyi bununla bir yöntemden çağırabilir miyim? –

+2

@MaxianNicu: Evet. Üye işlevi 'Class :: method()' ve bir 'object' nesnesi için, bunu 'caller (& Class :: method, & object)' olarak adlandırın. –

+0

Harika. İşe yaradı. Teşekkürler. –

7

Eğer keyfi bir argüman ile keyfi bir işlevi çağırmak yapmak isteyen tüm bu iki tür üzerinde sadece bir şablon varsa: Eğer genişletebilirsiniz

template <typename Function, typename Arg> 
void call_with_one(Function&& f, Arg&& arg) { 
    f(std::forward<Arg>(arg)); 
} 

o variadic yaparak args herhangi bir sayı ile çağırmak :

template <typename Function, typename... Arg> 
void call_with_any(Function&& f, Arg&&... args) { 
    std::forward<Function>(f)(std::forward<Arg>(args)...); 
} 
:

template <typename Function, typename... Arg> 
void call_with_any(Function f, Arg&&... args) { 
    f(std::forward<Arg>(args)...); 
} 

Ya da gerçekten f yanı bir yönlendirme referansı olmalı

Bunun yalnızca operator()'u uygulayan işlevler ve nesnelerle çalışacağını unutmayın. f bir işaretçi-üyesi ise, bu başarısız olur - yerine Mike Seymour önerileri kullanmanız gerekir.

+0

Yönlendirme referansı ile 'f 'almayı öneririm. – Quentin

+2

"Sadece" iş parçacığı kurucusu "gibi çalışmak için," f "bir üye işlev işaretçisi olduğunda da çalışmalıdır. –

+0

@MikeSeymour Cevabını kopyalamaktan ziyade cevabını vermek isterim :) – Barry