2017-02-16 134 views
1

我想編寫一個模板函數,它可以調用具有給定參數的函數。調用參數多於參數的函數/仿函數

例如,我可以寫一個簡單的調用函數:

template<class F, class... Args> 
inline auto invoke(F &&func, Args&&... args) -> decltype(auto) 
{ 
    return std::forward<F>(func)(std::forward<Args>(args)...); 
} 

invoke接受參數,f需要的相同的計數。但是,我想要這個模板函數允許額外的未使用的參數。 也就是說,我想寫一些代碼,如:

auto f = [] (auto a) {...}; 
invoke(f, 1, 2, 3); 

這裏,f接受只有一個參數的話,我希望invoke忽略除了第一個其他參數。 這可以很容易地通過獲得lambda的arity來實現,除非lambda是通用的。

由於f這裏是通用lambda,據我所知,沒有通用的方法來找出它的f的arity沒有明確實例化其template operator()<...>

我該如何保護我的invoke

回答

4

一種可能性:

#include <utility> 
#include <cstddef> 
#include <tuple> 

template <std::size_t... Is, typename F, typename Tuple> 
auto invoke_impl(int, std::index_sequence<Is...>, F&& func, Tuple&& args) 
    -> decltype(std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(args))...)) 
{ 
    return std::forward<F>(func)(std::get<Is>(std::forward<Tuple>(args))...); 
} 

template <std::size_t... Is, typename F, typename Tuple> 
decltype(auto) invoke_impl(char, std::index_sequence<Is...>, F&& func, Tuple&& args) 
{ 
    return invoke_impl(0 
        , std::index_sequence<Is..., sizeof...(Is)>{} 
        , std::forward<F>(func) 
        , std::forward<Tuple>(args)); 
} 

template <typename F, typename... Args> 
decltype(auto) invoke(F&& func, Args&&... args) 
{ 
    return invoke_impl(0 
        , std::index_sequence<>{} 
        , std::forward<F>(func) 
        , std::forward_as_tuple(std::forward<Args>(args)...)); 
} 

DEMO

+0

相依:對於一個可調用對象,這有時會調用'運算符()',其具有的參數數量最少。有可能稱爲最佳匹配? – felix

+0

@felix我沒有想法atm;也許可以從lambda對象繼承並導入它們的操作符(),但至少其中一個應該接受所有參數。我不能排除其他可能性。 –

+0

哦,看到聰明的模板元編程代碼總是令人印象深刻!謝謝。 – xylosper