C++ Logo

std-proposals

Advanced search

[std-proposals] Accessing a tuple element of index not known until runtime

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Sat, 11 Nov 2023 23:35:05 +0000
If we have a tuple as follows:

    tuple<int,char,long> mytuple;

Then we can access its elements as follows:

    get<0>(mytuple)
    get<1>(mytuple)
    get<2>(mytuple)

The index must be a compile-time constant in order for it to be a
template parameter to the template function "get". I've seen people
write if-else ladders and switch statements:

    void SetNull(unsigned const index, tuple<int,char,long> &t)
    {
        switch ( index )
        {
        case 0: get<0>(t) = {}; break;
        case 1: get<1>(t) = {}; break;
        case 2: get<2>(t) = {}; break;
        default: unreachable();
        }
    }

I think a lot of people would agree that the best way to allow runtime
access of tuple elements would be to use the 'visit' function. Have
there been any other proposals to simplify runtime access of tuple
elements?

My own version of 'visit' can be used as follows to set a tuple element to null:

    visit( index, mytuple, [](auto &x)
      {
          x = {};
      });

Here's the code behind it:

template<std::size_t I, typename ElemType, typename V>
void visit_detail2(std::size_t const index, ElemType &&e, V &&v)
{
    if ( I != index ) return;
    std::forward<V>(v)( std::forward<ElemType>(e) );
}

template<typename T, typename V, std::size_t... I>
void visit_detail1(std::size_t const index, T &&t, V &&v,
std::index_sequence<I...>)
{
    (..., visit_detail2<I>(index,std::get<I>(std::forward<T>(t)),std::forward<V>(v)));
}

template<typename T, typename V>
void visit(std::size_t const index, T &&t, V &&v)
{
    visit_detail1(index, std::forward<T>(t), std::forward<V>(v),
        std::make_index_sequence< std::tuple_size_v<typename
std::decay_t<T> > >());
}

Received on 2023-11-11 23:35:16