Как сделать лямбду explicit

#include <variant>
#include <iostream>

template <class... Ts>
struct MakeVisitor : Ts... {
  using Ts::operator()...;
};

template <class... Ts>
MakeVisitor(Ts ...) -> MakeVisitor<Ts...>;

template <class... Ty>
using Channel = std::variant<Ty...>;

decltype(auto) f(Channel<int, double, char> channel){
  MakeVisitor visitor(
      [](int val) { return 1; }, 
   // [](char val) { return 1; }, реализации для char нет, но все компилируется
      [](double val)  { return 1; });

  return std::visit(visitor, channel);
}

int main(){

    f(1);
    f(2.5);
    f('a'); // Не должно работать

    return 0;
}

Ответы (1 шт):

Автор решения: Chorkov

Если в класс визитора добавить, дополнительные операторы () для этих типов, то будут выбираться именно эти операторы, а не неявное преобразование типов.

template <class... Ts>
struct MakeVisitorExplicit : Ts... {
  MakeVisitorExplicit(Ts...args) : Ts(args)... {}
  using Ts::operator()...;

//private: // Можно объявить private или deleted, но сообщение об ошибке будет еще менее читабельным
  template<typename T>
  auto operator() (T) const
  {
      static_assert( false, "Access to usupported type" );
      return throw std::runtime_error("Access to usupported type");
  }
};
→ Ссылка