[英]Variadic function wrapper for any return type
我正在嘗試為要傳遞給它的任何函數編寫可變參數模板包裝,並且(可能)要返回其返回值。
現在,我想出了下面的代碼,但我真的很討厭我需要6種不同的函數重載,其中3種用於void返回類型,而3種用於非void返回類型。
// Void return type
// Template for non-member functions
template <typename Callable, typename... Args>
std::enable_if_t<std::is_void<std::result_of_t<Callable(Args...)> >::value
&& std::is_member_function_pointer<Callable>::value == false>
call(Callable worker, Args... params)
{
worker(std::forward<Args>(params)...);
}
// Template for member functions (general)
template <typename Callable, typename... Args>
std::enable_if_t<std::is_void<std::result_of_t<Callable(Args...)> >::value
&& std::is_member_function_pointer<Callable>::value>
call(Callable worker, Args... params)
{
call(std::forward<Callable>(worker), std::forward<Args>(params)...);
}
// Template for member functions (object instance extractor)
template <typename Callable, typename Object, typename... Args>
std::enable_if_t<std::is_void<std::result_of_t<Callable(Args...)> >::value
&& std::is_member_function_pointer<Callable>::value>
call(Callable worker, Object object, Args... params)
{
auto fn = std::mem_fn(worker);
fn(std::forward<Object>(object), std::forward<Args>(params)...);
}
// Non-void return types
// Template for non-member functions
template <typename Callable, typename... Args>
std::enable_if_t<std::is_void<std::result_of_t<Callable(Args...)> >::value == false
&& std::is_member_function_pointer<Callable>::value == false
, std::result_of_t<Callable(Args...)> >
call(Callable worker, Args... params)
{
return worker(std::forward<Args>(params)...);
}
// Template for member functions (general)
template <typename Callable, typename... Args>
std::enable_if_t<std::is_void<std::result_of_t<Callable(Args...)> >::value == false
&& std::is_member_function_pointer<Callable>::value
, std::result_of_t<Callable(Args...)> >
call(Callable worker, Args... params)
{
return call(std::forward<Callable>(worker), std::forward<Args>(params)...);
}
// Template for member functions (object instance extractor)
template <typename Callable, typename Object, typename... Args>
std::enable_if_t<std::is_void<std::result_of_t<Callable(Args...)> >::value == false
&& std::is_member_function_pointer<Callable>::value
, std::result_of_t<Callable(Args...)> >
call(Callable worker, Object object, Args... params)
{
auto fn = std::mem_fn(worker);
return fn(std::forward<Object>(object), std::forward<Args>(params)...);
}
有什么辦法可以消除其中的一些重載? 事實證明,這種方法可以很好地工作,但是從代碼方面來說,我真的希望更短一些。
這是SFINAE的較短版本(如果不需要,可以用decltype(auto)
代替)。
template <typename R, typename T, typename... Args, typename U,
typename... Params>
auto call(R (T::*arg)(Args...), U &&first, Params &&... params)
-> decltype((std::forward<T>(first).*
arg)(std::forward<Params>(params)...)) {
return (std::forward<T>(first).*arg)(std::forward<Params>(params)...);
}
template <typename F, typename... Ts>
auto call(F &&f, Ts &&... args)
-> decltype(std::forward<F>(f)(std::forward<Ts>(args)...)) {
return std::forward<F>(f)(std::forward<Ts>(args)...);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.