Thank you for spending time looking into `Embedded-Function`!

> (2) `function<bool()>` is contextually convertible to `bool`, such that `if (f)` means something different from `if (f())`. This is perfectly consistent with other types (e.g. `int`, e.g. `bool(*)()`) but again usually indicates a bug, and we've found bugs by replacing `std::function` with our own version that lacks this boolean conversion. Likewise assignment from, and comparison to, `nullptr`.

I agree with you. Keeping only a function like `is_empty()` might be a better design.

> (1) You can store `int(*)()` into `function<void()>` with no diagnostic at all. In my experience, this conversion is almost invariably a bug, and we've found bugs by replacing `std::function` with our own version that lacks this "lossy" conversion.

I'm not entirely sure it is necessary to warn or ban this behavior. Since `std::invoke_r<void>()` can invoke `int(*)()`, not being able to wrap both `int(*)(T)` and `void(*)(T)` into the same type-erased wrapper might feel a bit strange. But your concern is certainly reasonable.

> Your `fn<Sig, Cap>` seems to be missing an `Alignment` parameter. This means that there are callable objects it can't safely hold:

Thanks for pointing this out! The API of `ebd::fn` indeed lacks an `Alignment` parameter. I intentionally kept it as `alignof(std::max_align_t)` because I didn't want to give too many choices, as you yourself discussed in [design-space-for-std-function](https://quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/#:~:text=The%20upside%20of%20this%20idea%20is%20that%20it%20gives%20a%20great%20deal%20of%20power%20to%20the%20user.%20The%20downside%20is%20that%20it%20can%20induce%20paralysis%20in%20the%20user%20%E2%80%94%20giving%20too%20many%20choices%20can%20be%20counterproductive%2C%20especially%20if%20those%20choices%20usually%20don%E2%80%99t%20matter%20in%20the%20big%20picture.). This is indeed an insufficient part of the library if I were aiming for standardization.

I don't think adding something like `ebd::basic_fn` into the Standard Library is a good choice either, as you said, it gives too many 'design knobs'. My intention is simply to use this library as a vehicle for offering suggestions to improve `sg14::inplace_function`, rather than pushing for standardization. If this library can contribute to the improvement of `sg14::inplace_function`, I would be very pleased.

I was genuinely surprised to learn that few people are maintaining `sg14::inplace_function` at this point. However, I still believe our discussion is worthwhile for anyone who might want to continue progressing this toward the Standard Library at a more mature time.

Thanks again for your thoughtful feedback!

Best regards,
Kim J. Smith

On 2026-08-15 22:39:01, "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com> wrote:

On Sat, Aug 15, 2026 at 8:32 AM ycjin_kim via SG14 <sg14@lists.isocpp.org> wrote:
My name is Kim, a developer interested in embedded systems. I'd like to share a project I've been working on called "Embedded Function" and get the group's feedback.

`Embedded Function` is a lightweight, header-only library that provides a collection of heap-free polymorphic function wrappers (like `ebd::fn`, `ebd::unique_fn`, `ebd::fn_ref`). [...]
While the `stdext::inplace_function` implementation exists in the SG14 repository, it seems the standardization effort has not progressed recently. My library aims to be a modern, production-ready alternative. It offers several variants (`fn`, `unique_fn`, `classic_fn`, `fn_ref`) to cover different use cases, similar to what `std::function`, `std::copyable_function`, and `std::function_ref` provide.

Such a thing is useful, but personally I don't think it deserves to be put into the Standard Library. There are just too many "design knobs" to please everyone; and the STL is constrained by historical decisions. E.g. two of my pet peeves about `std::function`—
(1) You can store `int(*)()` into `function<void()>` with no diagnostic at all. In my experience, this conversion is almost invariably a bug, and we've found bugs by replacing `std::function` with our own version that lacks this "lossy" conversion.
(2) `function<bool()>` is contextually convertible to `bool`, such that `if (f)` means something different from `if (f())`. This is perfectly consistent with other types (e.g. `int`, e.g. `bool(*)()`) but again usually indicates a bug, and we've found bugs by replacing `std::function` with our own version that lacks this boolean conversion. Likewise assignment from, and comparison to, `nullptr`.

A new `function`-alike in the STL probably can't fix these issues; certainly `copyable_function` and `unique_function` did not fix them. At the very least, standardizing this kind of thing would mean arguing over each design decision, and ultimately putting each decision to a vote, which would produce the wrong answer for about half the decisions.
But a new third-party library could get these decisions "right" for its own users, and show other programmers the way to implement their own types that will be "right" for them.

That's basically what `sg14::inplace_function` is trying to do: get most decisions right and/or consistent with the STL, and provide a reference implementation for others to copy.
(Btw, note that I forked WG21-SG14/SG14 into Quuxplusone/SG14 quite a while ago now. I'm not aware that anyone is maintaining WG21-SG14/SG14 anymore; nor is anything in it being actively proposed by anyone at the moment.)

- Are there any features or design choices you think are missing or could be improved?

I didn't look closely, but just from looking at the API docs...
Your `fn<Sig, Cap>` seems to be missing an `Alignment` parameter. This means that there are callable objects it can't safely hold:
  struct alignas(128) F { int i_; void operator()() const; };
  fn<void() const, sizeof(F)> f = F();  // does this compile? Hard to tell; hopefully it compiles or not depending on the "implementation-defined" alignof(f)
  fn<void() const, sizeof(F), alignof(F)> f = F();  // This would be a "safer" interface

Cheers,
Arthur