ddd
ddd

Reputation: 23

Using an index in variadic function template

template <std::size_t N, class... Args>
using type = typename std::tuple_element<N, std::tuple<Args...>>::type;

template<typename ...Args, typename Func>
typename std::result_of<Func(Args...)>::type functionOnParams(Func fp, Args&&...args)
{
  using Indices = std::make_index_sequence<sizeof...(Args)>;

  int ints[2] = {1,2};
    return fp(std::forward<Args>( static_cast<type<index_of_args, Args...>>(ints[index_of_args++]) )...);
}

Hi, I have spent a number of hours trying to figure to how to get the index_of_args for the above code. Any help would be appreciated. My searches keep going around in circles. index_of_args does not exist. I need to generate this index for each element of the std::forward. Thank you

Upvotes: 0

Views: 152

Answers (1)

RedFog
RedFog

Reputation: 1015

you can get make an std::index_sequence from Args and pass them to a helper function (by template arguments deduction). and then do anything you want in the helper function.

template<typename Func, typename... Args, size_t... Is, typename RealArgs>
std::invoke_result_t<Func&&, Args&&...> helper(Func&& func, std::index_sequence<Is...>* indicesTag, std::tuple<Args...>* argsTypeTag, RealArgs&& args){
    return std::forward<Func>(func)(std::forward<Args>(std::forward<RealArgs>(args)[Is])...);
}
template<typename Func, typename... Args>
std::invoke_result_t<Func&&, Args&&...> functionOnParams(Func&& func, Args&&... args){
    int a[] = { 0, 1 };
    return helper(std::forward<Func>(func), (std::index_sequence_for<Args...>*)nullptr, (std::tuple<Args...>*)nullptr, a /* anything to replace the arguments */);
}


int main(){
    auto x = functionOnParams(std::plus<>(), 0, 1.0f);
    std::cout << x;
    return 0;
}

in the other hand, you can also use class template specialization to pass the std::index_sequence and Args.

template<typename, typename>
struct Helper;
template<typename... Args, size_t... Is>
struct Helper<std::index_sequence<Is...>, std::tuple<Args...>>{
    template<typename Func, typename RealArgs>
    static std::invoke_result_t<Func&&, Args&&...> call(Func&& func, RealArgs&& args){
        return std::forward<Func>(func)(std::forward<Args>(std::forward<RealArgs>(args)[Is])...);
    }
};
template<typename Func, typename... Args>
std::invoke_result_t<Func&&, Args&&...> functionOnParams(Func&& func, Args&&... args){
    int a[] = { 0, 1 };
    return Helper<std::index_sequence_for<Args...>, std::tuple<Args...>>::call(std::forward<Func>(func), a /* anything to replace the arguments */);
}

Upvotes: 1

Related Questions