Шаблон, который многие люди используют с вариантами С++ 17/boost, очень похож на инструкции switch. Например: (фрагмент из cppreference.com)
std::variant<int, long, double, std::string> v = ...;
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
Проблема заключается в том, что вы помещаете неправильный тип в посетителя или изменяете подпись варианта, но забудьте изменить посетителя. Вместо получения ошибки компиляции у вас будет неправильная лямбда-вызванная, обычно по умолчанию, или вы можете получить неявное преобразование, которое вы не планировали. Например:
v = 2.2;
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](float arg) { std::cout << std::fixed << arg << ' '; } // oops, this won't be called
}, v);
Операторы switch для классов enum более безопасны, потому что вы не можете написать оператор case, используя значение, которое не является частью перечисления. Точно так же я думаю, что было бы очень полезно, если вариант посетителя был ограничен подмножеством типов, содержащихся в варианте, плюс обработчик по умолчанию. Возможно ли реализовать что-то подобное?
EDIT: s/неявное литье/неявное преобразование /
EDIT2: Я бы хотел иметь полноценный обработчик [](auto)
. Я знаю, что удаление его приведет к ошибкам компиляции, если вы не обрабатываете каждый тип в варианте, но также удаляет функциональность из шаблона посетителя.