Date: Wed, 17 Dec 2025 15:58:19 -0500
On Wed, Dec 17, 2025 at 3:43 PM Farid Mehrabi via Std-Discussion <
std-discussion_at_[hidden]> wrote:
> Now you're skipping my response without enough proper attention and focus.
>
I think you should take a step back and consider that you did not actually
explain how to construct the `optional`. You explained the emplacer idiom,
but you didn't show how to use it to implement `transform`. If I haven't
understood you, it's because you haven't explained completely.
I've actually implemented the monadic operations for `optional`, so I know
how to use the emplacer idiom, so I've filled in the blanks in your email,
and I've explained why the approach is not perfect. If you meant something
different than what I meant, then you should show a working
proof-of-concept implementation of `transform`.
>
> 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:
> ```cpp
> template<typename T, typename F>
> auto optioal<T>::transform(F&&)
> -> optional<remove_cvref_t<invoke_result_t<F, T&>>>;
> ```
>
How do you construct an `optional<U>` where `U` is immovable and the value
of the contained `U` object is obtained by calling some function, call it
`f`, that returns `U` by value? Which constructor of `optional<U>` do you
call in order to do this?
Do you do it like this?
return optional<U>(emplacer{...});
If so, you are calling constructor #9 shown on cppreference:
https://en.cppreference.com/w/cpp/utility/optional/optional
And I am telling you that this will not do the right thing if `U` happens
to have a constructor like:
template <class V>
U(V&&);
> 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_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. Re: Std-Discussion Digest, Vol 81, Issue 10 (Brian Bi)
>>
>>
>>
>> ---------- Forwarded message ----------
>> From: Brian Bi <bbi5291_at_[hidden]>
>> To: std-discussion_at_[hidden]
>> Cc: Farid Mehrabi <farid.mehrabi_at_[hidden]>
>> Bcc:
>> Date: Wed, 17 Dec 2025 15:11:46 -0500
>> Subject: Re: [std-discussion] Std-Discussion Digest, Vol 81, Issue 10
>> What 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_at_[hidden]> 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_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. Re: Std-Discussion Digest, Vol 81, Issue 8 (Brian Bi)
>>>>
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: Brian Bi <bbi5291_at_[hidden]>
>>>> To: std-discussion_at_[hidden]
>>>> Cc: Farid Mehrabi <farid.mehrabi_at_[hidden]>
>>>> Bcc:
>>>> Date: Wed, 17 Dec 2025 14:17:57 -0500
>>>> Subject: Re: [std-discussion] Std-Discussion Digest, Vol 81, Issue 8
>>>>
>>>>
>>>> On Tue, Dec 16, 2025 at 10:28 AM Farid Mehrabi via Std-Discussion <
>>>> std-discussion_at_[hidden]> 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:
>>>>> ```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:
>>>>>
>>>>
>>>> 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_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
>>>>>>
>>>>> --
>>>>> Std-Discussion mailing list
>>>>> Std-Discussion_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>>>
>>>>
>>>>
>>>> --
>>>> *Brian Bi*
>>>> Std-Discussion mailing list
>>>> Std-Discussion_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>>
>>> --
>>> Std-Discussion mailing list
>>> Std-Discussion_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>
>>
>>
>> --
>> *Brian Bi*
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
std-discussion_at_[hidden]> wrote:
> Now you're skipping my response without enough proper attention and focus.
>
I think you should take a step back and consider that you did not actually
explain how to construct the `optional`. You explained the emplacer idiom,
but you didn't show how to use it to implement `transform`. If I haven't
understood you, it's because you haven't explained completely.
I've actually implemented the monadic operations for `optional`, so I know
how to use the emplacer idiom, so I've filled in the blanks in your email,
and I've explained why the approach is not perfect. If you meant something
different than what I meant, then you should show a working
proof-of-concept implementation of `transform`.
>
> 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:
> ```cpp
> template<typename T, typename F>
> auto optioal<T>::transform(F&&)
> -> optional<remove_cvref_t<invoke_result_t<F, T&>>>;
> ```
>
How do you construct an `optional<U>` where `U` is immovable and the value
of the contained `U` object is obtained by calling some function, call it
`f`, that returns `U` by value? Which constructor of `optional<U>` do you
call in order to do this?
Do you do it like this?
return optional<U>(emplacer{...});
If so, you are calling constructor #9 shown on cppreference:
https://en.cppreference.com/w/cpp/utility/optional/optional
And I am telling you that this will not do the right thing if `U` happens
to have a constructor like:
template <class V>
U(V&&);
> 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_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. Re: Std-Discussion Digest, Vol 81, Issue 10 (Brian Bi)
>>
>>
>>
>> ---------- Forwarded message ----------
>> From: Brian Bi <bbi5291_at_[hidden]>
>> To: std-discussion_at_[hidden]
>> Cc: Farid Mehrabi <farid.mehrabi_at_[hidden]>
>> Bcc:
>> Date: Wed, 17 Dec 2025 15:11:46 -0500
>> Subject: Re: [std-discussion] Std-Discussion Digest, Vol 81, Issue 10
>> What 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_at_[hidden]> 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_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. Re: Std-Discussion Digest, Vol 81, Issue 8 (Brian Bi)
>>>>
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: Brian Bi <bbi5291_at_[hidden]>
>>>> To: std-discussion_at_[hidden]
>>>> Cc: Farid Mehrabi <farid.mehrabi_at_[hidden]>
>>>> Bcc:
>>>> Date: Wed, 17 Dec 2025 14:17:57 -0500
>>>> Subject: Re: [std-discussion] Std-Discussion Digest, Vol 81, Issue 8
>>>>
>>>>
>>>> On Tue, Dec 16, 2025 at 10:28 AM Farid Mehrabi via Std-Discussion <
>>>> std-discussion_at_[hidden]> 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:
>>>>> ```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:
>>>>>
>>>>
>>>> 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_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
>>>>>>
>>>>> --
>>>>> Std-Discussion mailing list
>>>>> Std-Discussion_at_[hidden]
>>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>>>
>>>>
>>>>
>>>> --
>>>> *Brian Bi*
>>>> Std-Discussion mailing list
>>>> Std-Discussion_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>>
>>> --
>>> Std-Discussion mailing list
>>> Std-Discussion_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>>
>>
>>
>> --
>> *Brian Bi*
>> Std-Discussion mailing list
>> Std-Discussion_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>
-- *Brian Bi*
Received on 2025-12-17 20:58:36
