Date: Wed, 17 Dec 2025 17:00:28 -0500
On Wed, Dec 17, 2025 at 4:24 PM Farid Mehrabi <farid.mehrabi_at_[hidden]>
wrote:
> Here comes the implementation as well:
> ```cpp
> If (not this->has_value())
> return nullopt;
> /*define Local struct emplacer_t as before */
> return optional<U>
> { in_place, emplacer_t{ fn } };
> ```
> The `in_place_t` constructor template can be used to explicitly initialize
> an instance of `optional`. No extra constructor is needed.
>
> You're original problem was to use an "invocable" as an input to a public
> standard constructor. I gave you the emplacer idiom as the solution to
> replace an "invocable" with a "convertible" in my initial answer, assuming
> that you'd figure the proper constructor to apply the convertible. In this
> post I demonstrated the proper constructor too. I hope you can connect the
> dots at this point.
>
Okay, you want to make me do the work here. Fine.
Here's a complete working example of how to use the emplacer idiom to
construct an optional containing an immovable object, where that immovable
object is initialized by calling a function that returns it by value:
#include <functional>
#include <optional>
struct Immovable1 {
Immovable1(int) {}
Immovable1(const Immovable1&) = delete;
static Immovable1 make() { return {1}; }
};
template <class F>
struct Emplacer {
F&& f;
operator std::invoke_result_t<F>() const {
return std::invoke((F&&)f);
}
};
template <class F>
std::optional<std::invoke_result_t<F>> makeOptional(F&& f) {
return std::optional<std::invoke_result_t<F>>{std::in_place,
Emplacer{(F&&)f}};
}
auto o1 = makeOptional(Immovable1::make);
But let me show you a different value type for which this implementation
doesn't work:
struct Immovable2 {
Immovable2(int) {}
Immovable2(const Immovable2&) = delete;
Immovable2(auto&&... args) {
static_assert(sizeof...(args) > 100); // always false
}
static Immovable2 make() { return {1}; }
};
auto o2 = makeOptional(Immovable2::make); // triggers the static assertion
The reason why this fails is that instead of using the emplacer's
conversion function to initialize the `Immovable2` object, the `optional`
constructor will instantiate and attempt to use the `Immovable2(auto&&...)`
constructor (at which point the static assertion fires because there is
only one argument, not more than 100). So, you see, if the type has a
constructor like this, then the emplacer idiom doesn't work, because that
constructor is "too good" in overload resolution.
Here's the example on godbolt: https://godbolt.org/z/PzcK9rMah
I think that I explained this very clearly in one of my previous messages:
"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."
>
>
> 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!!!
>
> در تاریخ پنجشنبه ۱۸ دسامبر ۲۰۲۵، ۰۰:۲۸ Brian Bi <bbi5291_at_[hidden]> نوشت:
>
>>
>>
>> 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
>>>
>>
>>
>> --
>> *Brian Bi*
>>
>
wrote:
> Here comes the implementation as well:
> ```cpp
> If (not this->has_value())
> return nullopt;
> /*define Local struct emplacer_t as before */
> return optional<U>
> { in_place, emplacer_t{ fn } };
> ```
> The `in_place_t` constructor template can be used to explicitly initialize
> an instance of `optional`. No extra constructor is needed.
>
> You're original problem was to use an "invocable" as an input to a public
> standard constructor. I gave you the emplacer idiom as the solution to
> replace an "invocable" with a "convertible" in my initial answer, assuming
> that you'd figure the proper constructor to apply the convertible. In this
> post I demonstrated the proper constructor too. I hope you can connect the
> dots at this point.
>
Okay, you want to make me do the work here. Fine.
Here's a complete working example of how to use the emplacer idiom to
construct an optional containing an immovable object, where that immovable
object is initialized by calling a function that returns it by value:
#include <functional>
#include <optional>
struct Immovable1 {
Immovable1(int) {}
Immovable1(const Immovable1&) = delete;
static Immovable1 make() { return {1}; }
};
template <class F>
struct Emplacer {
F&& f;
operator std::invoke_result_t<F>() const {
return std::invoke((F&&)f);
}
};
template <class F>
std::optional<std::invoke_result_t<F>> makeOptional(F&& f) {
return std::optional<std::invoke_result_t<F>>{std::in_place,
Emplacer{(F&&)f}};
}
auto o1 = makeOptional(Immovable1::make);
But let me show you a different value type for which this implementation
doesn't work:
struct Immovable2 {
Immovable2(int) {}
Immovable2(const Immovable2&) = delete;
Immovable2(auto&&... args) {
static_assert(sizeof...(args) > 100); // always false
}
static Immovable2 make() { return {1}; }
};
auto o2 = makeOptional(Immovable2::make); // triggers the static assertion
The reason why this fails is that instead of using the emplacer's
conversion function to initialize the `Immovable2` object, the `optional`
constructor will instantiate and attempt to use the `Immovable2(auto&&...)`
constructor (at which point the static assertion fires because there is
only one argument, not more than 100). So, you see, if the type has a
constructor like this, then the emplacer idiom doesn't work, because that
constructor is "too good" in overload resolution.
Here's the example on godbolt: https://godbolt.org/z/PzcK9rMah
I think that I explained this very clearly in one of my previous messages:
"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."
>
>
> 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!!!
>
> در تاریخ پنجشنبه ۱۸ دسامبر ۲۰۲۵، ۰۰:۲۸ Brian Bi <bbi5291_at_[hidden]> نوشت:
>
>>
>>
>> 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
>>>
>>
>>
>> --
>> *Brian Bi*
>>
>
-- *Brian Bi*
Received on 2025-12-17 22:00:46
