https://www.godbolt.org/z/X4aphj

snippet.cpp
#include <tuple>
#include <type_traits>
 
struct add_tax_t {};
constexpr add_tax_t add_tax;
 
struct apply_discount_t {};
constexpr apply_discount_t apply_discount;
 
int now();
 
int total{0};
auto lambda = [total](auto op, auto... args) mutable
{
  using Op = decltype(op);
  using ArgsT = std::tuple<decltype(args)...>;
  if constexpr (std::is_same_v<Op, add_tax_t>) {
   auto [tax_rate] = ArgsT(args...);
   total += total * tax_rate;
   return total;
  } else if constexpr (std::is_same_v<Op, apply_discount_t>) {
   auto [amount, expiration] = ArgsT(args...);
   if (expiration < now()) {
     total -= std::max(amount, total);
   }
   return total;
  } else {
   static_assert(!sizeof(Op*), "Don't know what you are asking me to do.");
  }
};
 
int main()
{
    lambda(apply_discount, 5, 5);
    return lambda(add_tax, 0);
}

source: https://devblogs.microsoft.com/oldnewthing/20191107-00/?p=103071