Optimal way to access std::tuple element in runtime by index

て烟熏妆下的殇ゞ 提交于 2019-11-30 02:09:24

Assuming you pass something similar to a generic lambda, i.e. a function object with an overloaded function call operator:

#include <iostream>

struct Func
{
    template<class T>
    void operator()(T p)
    {
        std::cout << __PRETTY_FUNCTION__ << " : " << p << "\n";
    }
};

The you can build an array of function pointers:

#include <tuple>

template<int... Is> struct seq {};
template<int N, int... Is> struct gen_seq : gen_seq<N-1, N-1, Is...> {};
template<int... Is> struct gen_seq<0, Is...> : seq<Is...> {};

template<int N, class T, class F>
void apply_one(T& p, F func)
{
    func( std::get<N>(p) );
}

template<class T, class F, int... Is>
void apply(T& p, int index, F func, seq<Is...>)
{
    using FT = void(T&, F);
    static constexpr FT* arr[] = { &apply_one<Is, T, F>... };
    arr[index](p, func);
}

template<class T, class F>
void apply(T& p, int index, F func)
{
    apply(p, index, func, gen_seq<std::tuple_size<T>::value>{});
}

Usage example:

int main()
{
    std::tuple<int, double, char, double> t{1, 2.3, 4, 5.6};
    for(int i = 0; i < 4; ++i) apply(t, i, Func{});
}

clang++ also accepts an expansion applied to a pattern that contains a lambda expression:

static FT* arr[] = { [](T& p, F func){ func(std::get<Is>(p)); }... };

(although I've to admit that looks really weird)

g++4.8.1 rejects this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!