C++ Logo

std-discussion

Advanced search

Re: Std-Discussion Digest, Vol 81, Issue 8

From: Farid Mehrabi <farid.mehrabi_at_[hidden]>
Date: Tue, 16 Dec 2025 18:58:37 +0330
There's a very unpopular idiom about this. I call it the **emplacer**
idiom, which can be used in many different scenarios where the proper
constructor is not available. It relies on the C++20 mandated direct
initialization on returned objects:
```cpp
template<invocable<> F>
struct implacer_t{
      F&& fn;
      operator auto() const
     { return invoke(forward<F>(fn)); };
}; // ! emplacer
```
The `emplacer_t` class converts any references to invocable objects into
conversion to returned object, and can be fed to `emplace` members of any
standard class. It can also be used to call private constructors of classes
while using `make_unique` or `make_shared`. Usage is as simple as:
```cpp
auto fn = []<typname ...A>(A&&...v)
{ return T{forward<A>(v)}; };

my_obj.emplace
    ( emplacer_t
    { bind(fn,args...) } );
```
I just think that the emplacer idiom requires standard exposition. A few
convenience CPO should be added, that make the idiom publicly available to
standard library users:

- `default_emplacer` a CPO that can convert to any object with public
default constructor via calling the constructor.
- `emplace_args` embeds a forwarding tuple and returns an object
constructed from tuple elements upon conversion.
- `emplace_result` the most generic case that wraps the `emplacer_t` class
and returns an instance.
These 3 CPO can help in various situations of emplacement in user code.

Regards,
FM.

how am I supposed to end the twisted road of your hair in such a dark
night??
unless the candle of your face does shed some light upon my way!!!

در تاریخ دوشنبه ۱۵ دسامبر ۲۰۲۵،‏ ۱۵:۳۰ <
std-discussion-request_at_[hidden]> نوشت:

> Send Std-Discussion mailing list submissions to
> std-discussion_at_[hidden]
>
> To subscribe or unsubscribe via the World Wide Web, visit
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
> or, via email, send a message with subject or body 'help' to
> std-discussion-request_at_[hidden]
>
> You can reach the person managing the list at
> std-discussion-owner_at_[hidden]
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Std-Discussion digest..."
> Today's Topics:
>
> 1. Implementing std::optional<T>::transform (Rasheeq Azad)
>
>
>
> ---------- Forwarded message ----------
> From: Rasheeq Azad <rasheeqhere_at_[hidden]>
> To: Std-Discussion_at_[hidden]
> Cc:
> Bcc:
> Date: Sun, 14 Dec 2025 16:00:00 -0500
> Subject: [std-discussion] Implementing std::optional<T>::transform
> In the current draft, [optional.monadic] specifies that
> std::optional<T>::transform(F &&f) & shall do the following:
>
> > Let U be remove_cv_t<invoke_result_t<F, decltype(*val)>>.
> > Mandates: ...
> > [Note 1: There is no requirement that U is movable ([dcl.init.general]).
> > Returns: If *this contains a value, an optional<U> object whose
> contained value is direct-non-list-initialized with
> invoke(std::forward<F>(f), *val); otherwise, optional<U>().
>
> I'm wondering how this is supposed to be implemented. None of the
> standard constructors of std::optional<U> directly support
> initializing the contained object with an invocable. Both GCC
> libstdc++ [1a] [1b] [1c] and LLVM libc++ [2a] [2b] [2c] get around
> this by adding an internal-use-only (using a tag type that has a
> reserved name) constructor to std::optional<T> that takes the
> invocable and calls it to initialize the contained object. But this
> means that std::optional<T> relies on the *different specialization*
> std::optional<U> supporting this nonstandard constructor.
>
> As a consequence, neither library can fully cope with me defining my
> own specialization of std::optional. I hoped this was just an
> implementation bug and filed an issue with LLVM about it, [3], which
> contains a code example and my proposed solution (see also on
> [Godbolt]), but someone else pointed out that my proposed solution
> also has an edge case. So as far as I can tell right now, it seems
> impossible to implement std::optional<T>::transform while using only
> the standard interface of the other specialization std::optional<U>.
>
> If this really is the case, then the standard seems to have
> inadvertently prohibited program-defined specializations of
> std::optional with the addition of std::optional<T>::transform. I'm
> hoping to get more eyes on this question. If someone in this list
> could come up with a way to implement std::optional<T>::transform in a
> way that permits program-defined specializations (or say with more
> certainty that it's in fact not possible), that'd be great. Have I
> found a standard defect?
>
> - Rasheeq Azad
>
> [1a]:
> https://github.com/gcc-mirror/gcc/blob/ffa98429b93934be87f58bc3af481a69310aedaf/libstdc%2B%2B-v3/include/std/optional#L97
> [1b
> <https://github.com/gcc-mirror/gcc/blob/ffa98429b93934be87f58bc3af481a69310aedaf/libstdc%2B%2B-v3/include/std/optional#L97[1b>]:
>
> https://github.com/gcc-mirror/gcc/blob/ffa98429b93934be87f58bc3af481a69310aedaf/libstdc%2B%2B-v3/include/std/optional#L1490-L1493
> [1c
> <https://github.com/gcc-mirror/gcc/blob/ffa98429b93934be87f58bc3af481a69310aedaf/libstdc%2B%2B-v3/include/std/optional#L1490-L1493[1c>]:
>
> https://github.com/gcc-mirror/gcc/blob/ffa98429b93934be87f58bc3af481a69310aedaf/libstdc%2B%2B-v3/include/std/optional#L1391
> [2a
> <https://github.com/gcc-mirror/gcc/blob/ffa98429b93934be87f58bc3af481a69310aedaf/libstdc%2B%2B-v3/include/std/optional#L1391[2a>]:
>
> https://github.com/llvm/llvm-project/blob/9975cb166ea3925738abb8d0db0028e418315eda/libcxx/include/optional#L369
> [2b
> <https://github.com/llvm/llvm-project/blob/9975cb166ea3925738abb8d0db0028e418315eda/libcxx/include/optional#L369[2b>]:
>
> https://github.com/llvm/llvm-project/blob/9975cb166ea3925738abb8d0db0028e418315eda/libcxx/include/optional#L925-L927
> [2c
> <https://github.com/llvm/llvm-project/blob/9975cb166ea3925738abb8d0db0028e418315eda/libcxx/include/optional#L925-L927[2c>]:
>
> https://github.com/llvm/llvm-project/blob/9975cb166ea3925738abb8d0db0028e418315eda/libcxx/include/optional#L1144
> [3]: https://github.com/llvm/llvm-project/issues/172197
> [Godbolt]:
> https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAMzwBtMA7AQwFtMQByARg9KtQYEAysib0QXACx8BBAKoBnTAAUAHpwAMvAFYgATKVpMGoZAFI9AIQuXSS%2BsgJ4BlRugDCqWgFcWDCaRuADJ4DJgAcr4ARpjEIACs8aQADqgKhM4Mnj5%2BAanpTgIhYZEsMXGJdpgOhQxCBEzEBNm%2B/lxVNZn1jQTFEdGxCUkKDU0tue0jPX2l5UMAlHao3sTI7BwWAMyhyD5YANRmm%2B78xCxMBEfYZhoAgls7e5iHx84jxJisVzf3etsMu28ByO7neoWA3zuPweAKeL08yVqYkh9zuuyYCgU%2BxYAE8APpRVBeQ4Adks%2BwA9BT9kx9sliKhgMRWABaLA0MLofYEHHJZ4ASWxeGACAI%2BwA7sYxUR9go%2Bcg8GI8AAvZ4jdAgECoRGZMT7U4/fb7ZAIRr7VRHax3ZLeKK0PDIECG/aYVTJe0KsW4glE2gQQnE1TzfYgc0QIOk8lmEkAEWd3oDfoTvosADY08GjjH9lh6ARMJbnQA/ZNeCCZsmkuObK2o25G13uh2Efba2IXEj7RPl40CEaR/YfAgrBjmy1V%2BP4xOtvnMojEMCQYNoBj96Pkocj7FT30QRfdoPzcfRuNQ2OFqF3fMsd0XAvHK7GoyY2UEDVanUCZHHUu0R/r513m8RwaSiJRBDxMV12NU1iFlRgnDCWgXmzPRj3PGtnW8BhMgHX86Q%2BcDLhrUCiMg0iEPQ6tySpWUmAAN0wLlaSiHF80OAAxDQzAATg4sxbniMxLE2RcfhtO0HSdO4jVoj56HoqVsUwMpYgUZ0VxGRs4O1JE/WDBhUFdNZERDCjBB7aCTw0vt8zdHTP2YP0GG8WhaF0yCDKM1QTLFUNdN1fSB2smSZz0iAAq/ZDNMuPRU0zTZs1zTB8wvOsjWvW9UuOdEXwAOgKgAVR8PgAR28PBCP2PAFDxGLiGApw7UwPF6JBX9SH2QqCrylEjRi7SXTdD0W0ipyIFCPFbzWSDOsKw44rTHqCGDUN6UwIiIHVTVTklYh0BBYrNmwCAVp6iso3PS9625FSsvvdxcqxIJOqe/YeqO7BB0wcrKo26ravqxq8Ga1r2p3LxOtCDIlVVYg8XtEYQSCb44rmnq%2Bt7Vc7PpIam09MLAomhgpqMGaCChnCnFh2IEZq4j3BR479loOaFvTOLltWgiNoQiBWdfd9dsaA7jk%2B075nO4Krpu2iV0YppwSxoDHBILFjC5VACAQWJ9mAEgcRzFKmDoLFUBYQh8wO67%2Btswbp1NWrFJ8TAexi/ZDOMzBTIA0KjU3YhRyYMCELyojQmqfYxMS8yCEg8sw4QiO/0w0KQpugb7P2IsxrESzKzwKgIEd1qxG8V35mDdaiLyksIf0qjoVCzKjGy9weT5Zg2H2fjmcz3GmG8GUCGZVdThYCAOPZtMqEzRbU/uDDax%2BWiEFQcV9gAKn5TeJWWWguTwG96DYQRuVHhRx/2CLtd11AFfcph0CxdILaMYgjyvO7W4ejvGFYZ4vcvoqzFD/OCvsbpTyoGlI0bY5ydiwLsP%2BEBB5EHmJZRacUBwB1HNtEALB76u1nuWRuZ5qI/BbneEEf8u6AMfP3OCqDUCC01LnFO7hfxXE1CPYwl8SATynmmGec9UyRiwukEw%2Bw5AoW%2BgQxidV6IfCoJBEEoR6KoAANYtUIq5OODMOKdU4fPa4x0YHVSLiXZ25dywXWdP7FKW48FsJBHIK4xNSZMDWJ1MBEAzDxGsIteI2YWSPmkRAo0ETvrDkDiwkAajNGuzwcLfaIIgHUEWDzIiR4F6RJPJXMxJ4XS0CUFExxb5WGOW/O4Vxx0SEL3Tj8UIXoTYMHzrWI0TjKnsM4czMoW1ylxJJtNTAnUR7l2ye02Jzifz10fGUPQMiyh5R4WPfhvi4q/gqe2eci4JlNxup0vSII8FghMI%2BKgLAoIxyWSsvhZxfH%2BL8TGFBQ9mHuzTGUC6pSYlJP4RcdZaEyTWXiO4BgFgDBdl3J8iZVY9mhULtQS5wY8FoCHvCEEW8LnEXJNUEpKLlhXPcBi8FwciJ%2BNBeCtKgEBnTPcImR8qAoiLKiMsi%2B491mpk2R%2BbZnZExwtltSW47gADSi5r72iiOYKwNgpldMOlwkAtyr41W5DrVsVAqBuFiJ/A5NK5UzJ9F4OZURNgyMZay3h7K/HWCCf6X0XYvk4O3Iav0UQYV5KpbGDgixaCcHiLwfwHAtCkFQJwIl0qrCymWKsZ4Ww9C8AIJob1iwdZP0GOWUgGiQCpk2HlRIqY9AaAAByphJBoDQPFEhcCSL6jgkheAsAkOW0ggbg2ho4LwBQIANCkETUG71pA4CwCQK6TAyBXlkAoCg4gwAFDKGMNUIQa9xSBp4KQNAN46AXEyPOpCS716tt4Bu5IdBBjohMJBBqDANHrvNie%2BgxBwgAM4Eeu9p7iAAHkh77pXUmwIqgx23BnV2jt/6x31HwIG3g/BBAiDEOwKQMhBCKBUOoftpBdDtCMCYFANgbCGBBl2pcIbHIgZZOqLMUqAmWD0MgfY5G3wSqzBKqjNheCEOIMQPAWAiMZqvU4NghVfS8cWAoaNax9B2DfKEXdi7l2roTR8dgPbxTMmSJwHgPq/UBr/e27AAHx3znNCWlkqZJBPmMMAa%2BYzr3BggOG6jnVcCEE7HG%2BYCak2V0zSATYqY8qSEkJsEkPEuCbD0DxHiGgAtFprZwetLbdMvrsN23tnmtMcHjQl9D7aPP9q8wrdILhJBAA%3D%3D
>
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

Received on 2025-12-16 15:28:34