c++variantstdtuplec++23

converting tuple to variant problems


I need to access a value in std::tuple by index at run time. For that purpose I wrote a function that returns a std::variant with the same types initialized for the specified index. Implementation involves recursive template instantiations:

template<std::size_t N>
constexpr auto get_n = [](/*tuple-like*/auto&& t, std::size_t index)
{
    using variant_type = decltype(std::apply([](auto&&... v){
        return std::variant<std::monostate, std::remove_cvref_t<decltype(v)>...>{};
    }, t));

    constexpr auto size = std::tuple_size_v<std::remove_cvref_t<decltype(t)>>;

    if constexpr(N > size)
        return variant_type{};
    else 
    {
        if(N == index + 1)
            return variant_type(std::in_place_index<N>, std::get<N - 1>(t));
        else
            return get_n<N + 1>(t, index);
    }
};

constexpr auto tuple_to_variant(/*tuple-like*/auto&& t, std::size_t index)
{
    return get_n<1>(std::forward<decltype(t)>(t), index);
}

I'm using c++23 compilers. The problem is that only gcc compiles without errors. The clang and MSVC compilers go into infinite instantiation loop. Is that a bug in compilers? How can I fix this code that it compiles in all three compilers?

Here is Compiler Explorer demo


Solution

  • Works if you use

    template<std::size_t N>
    constexpr auto get_n(/*tuple-like*/auto&& t, std::size_t index)
    

    instead. There's no reason for get_n to be a lambda.