Now you're skipping my response without enough proper attention and focus.
The emplacer object is constructed and explicitly converted by the impelementation. The point of using emplacer idiom is to replace a function call with a conversion, so the constructor/`emplace` member of result object won't need an extra move construction. The result object `optional<U>` has an explicit and fully specified type, so there will be no mistakes:```cpptemplate<typename T, typename F>auto optioal<T>::transform(F&&)-> optional<remove_cvref_t<invoke_result_t<F, T&>>>;```
Result type is already known, So there's only a simple construction/emplace required for the result. Depending on implementation, emplacer idiom may or may not be required. Anything `F` returns, will be stripped off its qualifiers before converting into an `optional`. Compile fails if proper copy/move constructors are unavailable. Now If your argument is based on constraining standard library, that'll be a total reboot not limited to a specific member function of a specific class.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@lists.isocpp.org> نوشت:Send Std-Discussion mailing list submissions to
std-discussion@lists.isocpp.org
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@lists.isocpp.org
You can reach the person managing the list at
std-discussion-owner@lists.isocpp.org
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Std-Discussion digest..."
Today's Topics:
1. Re: Std-Discussion Digest, Vol 81, Issue 10 (Brian Bi)
---------- Forwarded message ----------
From: Brian Bi <bbi5291@gmail.com>
To: std-discussion@lists.isocpp.org
Cc: Farid Mehrabi <farid.mehrabi@gmail.com>
Bcc:
Date: Wed, 17 Dec 2025 15:11:46 -0500
Subject: Re: [std-discussion] Std-Discussion Digest, Vol 81, Issue 10Std-Discussion mailing listWhat you're calling `U` is what I called `T` in my example (the type that needs to be constructed).If the type that needs to be constructed has an unconstrained constructor template, that constructor template will be used and the emplacer's conversion function will not be used. That is the problem.On Wed, Dec 17, 2025 at 3:09 PM Farid Mehrabi via Std-Discussion <std-discussion@lists.isocpp.org> wrote:I guess you're missinterpreting the usage of `transform`. The output type `U` is deduced from `invoke_result_t<F>`. It has nothing to do with original `T`. If the `F` instance doesn't mutate the original `T` instance, it won't be modified. `T` and `U` don't need to have any relation; the requirment is `invocable<F(T&)>`(`T` reference gets same qualifiers as `this`), and `U` is deduced to `auto{f(t)}`.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@lists.isocpp.org> نوشت:Send Std-Discussion mailing list submissions to
std-discussion@lists.isocpp.org
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@lists.isocpp.org
You can reach the person managing the list at
std-discussion-owner@lists.isocpp.org
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Std-Discussion digest..."
Today's Topics:
1. Re: Std-Discussion Digest, Vol 81, Issue 8 (Brian Bi)
---------- Forwarded message ----------
From: Brian Bi <bbi5291@gmail.com>
To: std-discussion@lists.isocpp.org
Cc: Farid Mehrabi <farid.mehrabi@gmail.com>
Bcc:
Date: Wed, 17 Dec 2025 14:17:57 -0500
Subject: Re: [std-discussion] Std-Discussion Digest, Vol 81, Issue 8Std-Discussion mailing listOn Tue, Dec 16, 2025 at 10:28 AM Farid Mehrabi via Std-Discussion <std-discussion@lists.isocpp.org> wrote: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:```cpptemplate<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:```cppauto 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:I am sure that the standard library implementors know this trick. The problem is that it doesn't actually let you implement the spec perfectly. Consider the case of an `optional<T>` where `T` has a constructor like this:template <class U>T(U&&);In other words, there is an implicit conversion from any type to `T`. Now, if you attempt to construct a `T` using what you've called the emplacer idiom, this constructor will be called, since it will win overload resolution compared with the alternative of calling the move constructor of `T` (with the T&& binding to the T returned by the emplacer's conversion function).So, I think the only way to actually implement the spec is to add an extra constructor like the standard library devs have done. This does appear to be an issue with the spec since it breaks user-defined specializations of `optional` like Rasheeg points out, and LWG should decide what to do about it, e.g.:
- ban user-defined specializations of `optional`?
- recommend to LEWG that they add the necessary constructor to the public interface?
- modify the spec so that it explicitly uses the emplacer idiom (thus not requiring support for cases where the emplacer idiom doesn't work)?
- `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@lists.isocpp.org> نوشت:Send Std-Discussion mailing list submissions to
std-discussion@lists.isocpp.org
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@lists.isocpp.org
You can reach the person managing the list at
std-discussion-owner@lists.isocpp.org
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@gmail.com>
To: Std-Discussion@lists.isocpp.org
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#L1490-L1493
[1c]: 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#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@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
--Brian Bi
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
--Brian Bi
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion