Как сделать лямбду 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");
}
};