我在 Linux 上使用 C ,我需要開發一個通用庫來簡化多執行緒開發。
好吧,我知道 C 11 中有一些多執行緒機制,例如std::async,std::future等等。但pthread由于某些歷史原因,我必須使用。
基本上,我想做的是制作一個非常簡單的模板函式,有點像std::future. 這里是。
template<typename S>
struct signature;
template<typename R, typename... Args>
struct signature<R(*)(Args...)> {
using return_type = R;
using argument_type = std::tuple<R(*)(Args...), Args...>; // f, args...
};
template<typename F, typename... Args>
void func(F* f, Args&&... args) {
typename signature<decltype(f)>::argument_type tp = std::make_tuple(f, std::forward<Args>(args)...);
pthread_t td;
pthread_create(&td, nullptr, [](void *p){
auto param = static_cast<typename signature<decltype(f)>::argument_type*>(p);
std::get<0>(*param)(std::get<1>(*param)); // ???
return (void*)nullptr;
}, &tp);
}
void f(int a) {}
void f2(int a, int b) {}
int main() {
func(f, 1);
// func(f2, 2, 2); ERROR!
return 0;
}
總之,我嘗試將函式的引數包裝成一個元組,并將元組傳遞給 的第三個引數pthread_create,也就是一個labmda。
所以在這段代碼中,std::get<0>(*param)是函式,元組的其余部分*param是應該傳遞給函式的引數串列。但我不知道如何擴展它。顯然,這std::get<0>(*param)(std::get<1>(*param));是不行的,因為它只能處理一個引數的函式。如果我想傳遞一個帶有兩個引數的函式,我會得到一個錯誤。
那么如何擴展那里的元組呢?
順便說一句,請忽略其他問題,例如為什么不呼叫pthread_join. 我只是在這里洗掉它們以最小化我的帖子。
uj5u.com熱心網友回復:
如評論中所述,std::apply適合您的情況。
pthread_create(
&td, nullptr,
[](void* p) {
auto param = static_cast<typename signature<decltype(f)>::argument_type*>(p);
std::apply([](auto& f, auto&&... args) {
f(std::forward<decltype(args)>(args)...);
}, *param);
return (void*)nullptr;
},
&tp);
演示。
uj5u.com熱心網友回復:
如果您不能使用 C 17 ( std::apply()),我想您必須添加一個間接級別...
你func()可以打電話給func2()
template<typename F, typename... Args>
void func(F* f, Args&&... args) {
func2(std::make_index_sequence<sizeof...(Args)>{}, f,
std::forward<Args>(args)...);
}
它還接收一個模板序列的索引,所以你的 lambda,現在在里面func2()(我已經洗掉了 pthread 部分......對不起)可以寫成如下
template <std::size_t ... Is, typename F, typename ... Args>
void func2 (std::index_sequence<Is...>, F * f, Args && ... args) {
typename signature<decltype(f)>::argument_type tp = std::make_tuple(f, std::forward<Args>(args)...);
[](void *p){
auto param = static_cast<typename signature<decltype(f)>::argument_type*>(p);
std::get<0>(*param)(std::get<1u Is>(*param)...);
return (void*)nullptr; }(&tp);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/408799.html
標籤:
