I'm trying to dispatch a variant inside a variant with the visitor overload pattern. However I can't seem to fit the parameters to what is expected. I get this (truncated, for more output see compiler explorer link):
error: no matching function for call to 'visit ...'
Here's my code. What am I overlooking?
#include <variant>
#include <cstdio>
template <typename... Ts>
struct overload : Ts...
{
using Ts::operator() ...;
};
int main() {
struct StateA{};
struct StateB{};
struct StateC{};
using state_type = std::variant<StateA, StateB, StateC>;
auto state = state_type{StateA{}};
struct EventA{};
struct EventB{};
struct WifiConnectedNote{};
struct ErrorNote{};
using QueueVariantType = std::variant<std::monostate, WifiConnectedNote, ErrorNote>;
using event_type = std::variant<std::monostate, QueueVariantType, EventA, EventB>;
auto event = event_type{EventA{}};
for (size_t i=0; i < 10; i++) {
state = std::visit(overload{
[&](QueueVariantType&& variant, auto&& state_tmp) -> state_type {
std::visit(overload{
[&](WifiConnectedNote&&, auto&&){
printf("WifiConnectedNote A\n");
},
[&](ErrorNote&&, auto&&){
printf("ErrorNote A\n");
},
[&](auto&&, auto&&){
printf("Other in Queue variant\n");
},
}, std::forward<decltype(variant)>(variant), std::forward<decltype(state_tmp)>(state_tmp));
return StateC{};
},
[&](auto&&, const StateA&) -> state_type {
printf("State A\n");
return StateC{};
},
[&](auto&&, const StateB&) -> state_type {
printf("State B\n");
return StateA{};
},
[&](auto&&, const StateC&) -> state_type {
printf("State C");
return StateB{};
},
}, std::move(event), state);
}
}
You are missing an overload case for the outer std::visit
for event==std::monostate
. Either provide one or remove the state from the variant type.
[&](std::monostate, auto&& ) -> state_type {
; // Do stuff here
}
state_tmp
is not used in the inner std::visit
. If i remove it and the auto&&
from the lambda signatures, the code compiles and runs. But is this what you want ? Remember that state_tmp
is not the variant type itself, but the underlying type resolved by the outer std::visit. That's why the inner visit fails.
Hope you can take from here !