我需要在运行时通过索引访问
std::tuple
中的值。为此,我编写了一个函数,它返回一个 std::variant
,其类型与为指定索引初始化的类型相同。实现涉及递归模板实例化:
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);
}
我正在使用 c++23 编译器。问题是只有gcc编译没有错误。 clang 和 MSVC 编译器进入无限实例化循环。这是编译器中的错误吗?我如何修复在所有三个编译器中编译的代码?
这是编译器资源管理器演示
如果你使用就可以工作
template<std::size_t N>
constexpr auto get_n(/*tuple-like*/auto&& t, std::size_t index)
相反。
get_n
没有理由成为 lambda。