[英]How can a recover the non-typename template argument from each type in a variadic pack of template classes?
[英]How to extract lambda's Return Type and Variadic Parameters Pack back from general template<typename T>
我想創建一個模板化的類或函數,它接收一個lambda,並將它放在std :: function <>內部.Lambda可以有任意數量的輸入參數[](int a,float b,...)std :: function <>應該對應lambda的operator()的類型
template <typename T>
void getLambda(T t) {
// typedef lambda_traits::ret_type RetType; ??
// typedef lambda_traits::param_tuple --> somehow back to parameter pack Args...
std::function<RetType(Args...)> fun(t);
}
int main() {
int x = 0;
getLambda([&x](int a, float b, Person c){});
}
所以我需要以某種方式提取返回類型和參數包
這里的答案建議在lambda的:: operator()上使用部分規范
template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
enum { arity = sizeof...(Args) };
// arity is the number of arguments.
typedef ReturnType result_type;
template <size_t i>
struct arg
{
typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
// the i-th argument is equivalent to the i-th tuple element of a tuple
// composed of those arguments.
};
};
但我需要一種方法將元組<>轉換回參數包,以創建一個正確的std :: function <>實例化
template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{};
template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
using result_type = ReturnType;
using arg_tuple = std::tuple<Args...>;
static constexpr auto arity = sizeof...(Args);
};
template <class F, std::size_t ... Is, class T>
auto lambda_to_func_impl(F f, std::index_sequence<Is...>, T) {
return std::function<typename T::result_type(std::tuple_element_t<Is, typename T::arg_tuple>...)>(f);
}
template <class F>
auto lambda_to_func(F f) {
using traits = function_traits<F>;
return lambda_to_func_impl(f, std::make_index_sequence<traits::arity>{}, traits{});
}
上面的代碼應該做你想要的。 如您所見,主要思想是創建一個整數包。 這是variadics的非類型模板。 我不知道你可以使用這種方法而不調用另一個函數的任何技術,所以通常在這些帶有元組的情況下你會看到一個嵌套的“impl”函數來完成所有的工作。 獲得整數包之后,在訪問元組時展開它(用於獲取值)。
在風格上注意:使用using
而不是typename
, 尤其是在模板繁重的代碼中,因為前者也可以使用別名模板。 並且不使用該enum
技巧來存儲靜態值而不使用空間; 編譯器無論如何都會優化它,只需使用static constexpr
整數static constexpr
清楚了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.