Skip to content

Instantly share code, notes, and snippets.

@yujincheng08
Created March 5, 2025 02:14
Show Gist options
  • Save yujincheng08/717336604c5aa78246a642313ef6f438 to your computer and use it in GitHub Desktop.
Save yujincheng08/717336604c5aa78246a642313ef6f438 to your computer and use it in GitHub Desktop.
y combinator for static lambda without deducing this and std::function
#include <type_traits>
template<typename, typename>
struct YComb;
template<typename F, typename Ret, typename...Args>
struct YComb<F, Ret(Args...)>{
constexpr YComb(F&& f){
}
static constexpr Ret operator()(Args... args) {
return self(args...);
}
inline static constexpr Ret(*self)(Args...) = static_cast<Ret(*)(Args...)>(&F::template operator()<YComb::operator()>);
};
template<typename F>
YComb(F&&) -> YComb<F, decltype(F::template operator()<&decltype([] static {})::operator()>)>;
template<typename F>
concept Self = std::is_function_v<std::remove_pointer_t<F>>;
inline static YComb fib = []<Self auto self>(unsigned x) static -> unsigned {
if (x < 2) return x;
return self(x - 1) + self(x - 2);
};
int main()
{
static_assert(fib(8) == 21);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment