Tenho vários std::variant
tipos possivelmente repetidos e gostaria de incrementar o índice ativo da variante.
Aqui está um exemplo que demonstra o que eu gostaria de fazer:
template <typename... Ts>
bool update_variant(std::variant<Ts>& v, std::tuple<work_generator<Ts>>& gen) {
return visit_with_index([&]<size_t Index /* the active index */>(auto& e) {
if (e.done()) {
// we are done with e
constexpr size_t next_index = Index + 1;
if constexpr (next_index == sizeof...(Ts)) {
// no more other work to do
return false;
} else {
// still have other work to do so we move on to the next variant alternative
v.emplace(
std::in_place_index_t<next_index>{},
std::get<next_index>(gen).create_worker()
);
return true;
}
} else {
// do some work on e, so e gets closer to the done state
e.do_some_work();
return true;
}
}, v);
}
Para implementar isso, parece que preciso de algo semelhante ao visit_with_index
acima, que me forneça o índice atual como um valor de tempo de compilação.
Além de escrever minha própria versão do visit_with_index
acima, que efetivamente é escrever minha própria versão de std::visit
, há alguma maneira mais simples de conseguir o que quero sem realizar mais de uma pesquisa por índice?
Eu usaria
visit
no índice "diretamente" .Primeiro
Então
Demonstração
Se tudo o que você se importa é uma única visita, então o Boost.Mp11
mp_with_index
já é o que você quer:Aqui
I
está umintegral_constant<size_t, V>
para algunsV
, para que possa ser usado diretamente comostd::get<I>(x)
.Internamente,
mp_with_index<N>(i, f)
é basicamente umswitch (i)
conjunto de valores de0
paraN - 1
.