#pragma once template struct YCombinator { // NOTE: implicit constructor allows initializing this Func func; template decltype(auto) operator()(Ts&&... args) const { // NOTE: static_cast(args)... is equivalent to std::forward(args)... // written this way so that we don't have to include , as well as reducing template instanciations to help compile time return func(*this, static_cast(args)...); } };