C++ std::get fails

后端 未结 4 1669
抹茶落季
抹茶落季 2021-01-12 20:48

How do I use a variable to index into a tuple using std::get<>? I have the following code:

#include 
#include 
using n         


        
4条回答
  •  [愿得一人]
    2021-01-12 21:50

    The likely answer that you should adopt is to just use an array, vector, or other kind of indexed container.


    In the event that the tuple elements are not homogeneous types and you actually do need an answer for that case, it's a bit complex. This is because types need to be known at compile time. So where you think you could do std::cout << get_from_tuple(a_tuple, index) for example, this can't work as easily as you think it can because the operator<< overload for sending the object to the standard output stream is selected at compile time. Obviously, this means that the index must be known at compile time, too -- otherwise we can't know the type of the tuple element.

    However, it is possible to build a template function that can, in fact, implement exactly this behavior. The end result, when compiled, is a conditional tree that is capable of handling each element in the tuple, but we enlist the compiler to help us build that conditional tree.

    What I will build here is a function that, given a tuple, index, and functor, will invoke the functor, forwarding that particular tuple item, and will then return true. If the index is out of range, it will return false.

    If the functor is not able to be called with every element in the tuple, the template function will fail to instantiate.

    The final solution looks like this:

    #include 
    #include 
    
    namespace detail {
        template 
        struct size_wrapper { };
    
        template 
        bool visit_tuple_index_impl(Tup && t, std::size_t index, V && visitor, size_wrapper)
        {
            if (index == I - 1) {
                visitor(std::get(std::forward(t)));
                return true;
            }
    
            return visit_tuple_index_impl(std::forward(t), index, visitor, size_wrapper());
        }
    
        template 
        bool visit_tuple_index_impl(Tup &&, std::size_t, V &&, size_wrapper<0>)
        {
            return false;
        }
    }
    
    template 
    bool visit_tuple_index(Tup && t, std::size_t index, V && visitor)
    {
        return detail::visit_tuple_index_impl(
            std::forward(t),
            index,
            std::forward(visitor),
            detail::size_wrapper::type>::value>()
        );
    }
    

提交回复
热议问题