Date: Mon, 21 Aug 2023 11:32:52 -0300
What about: https://godbolt.org/z/1ebe9E3a3
#include <mutex>
#include <optional>
extern std::mutex FuncThatReturnsMutex();
template<class T, class Fn>
void reemplace(std::optional<T>& opt, Fn&& fn)
{
if (!opt)
opt.emplace();
T* buf = std::addressof(*opt);
buf->~T();
new (buf) T(fn());
}
int main()
{
std::optional<std::mutex> om;
reemplace(om, FuncThatReturnsMutex);
// om = FuncThatReturnsMutex();
}
Breno G.
On Mon, Aug 21, 2023 at 11:16 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:
> The following is currently impossible in C++26:
>
> extern std::mutex FuncThatReturnsMutex(void);
>
> int main(void)
> {
> std::optional<std::mutex> om;
> om = FuncThatReturnsMutex();
> }
>
> It's impossible because a mutex must be either copiable or movable in
> order to assign it to an 'optional'. We have the same problem with
> 'std::variant', 'std::any', and lots of classes in other libraries like
> Boost.
>
> Currently we can write constructors and assignment operators that take:
> • an Lvalue ref
> • an Rvalue ref
>
> What if we had a third kind whose argument must be a prvalue? An
> implementation of 'optional' would look something like as follows:
>
> template <typename T>
> class optional {
> bool bool_has_value = false;
> alignas(T) char unsigned buf[sizeof(T)];
> public:
> optional(T ^^arg) : buf(arg)
> {
>
> }
>
> optional &operator=(T ^^arg) : buf(arg)
> {
> if ( this->bool_has_value )
> {
> static_cast<T*>(static_cast<void*>(&buf))->~T();
> this->bool_has_value = false;
> }
>
> __emplace;
>
> this->bool_has_value = true;
>
> return *this;
> }
> };
>
> In the case of the constructor, if 'FuncThatReturnsMutex' throws an
> exception, then the 'optional' constructor as a whole will throw an
> exception, so no problem there.
>
> But in the case of the assignment operator, we have a problem if
> 'FuncThatReturnsMutex' throws, so we need control over when the prvalue
> gets generated -- and that's why I have the '__emplace' keyword there.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
#include <mutex>
#include <optional>
extern std::mutex FuncThatReturnsMutex();
template<class T, class Fn>
void reemplace(std::optional<T>& opt, Fn&& fn)
{
if (!opt)
opt.emplace();
T* buf = std::addressof(*opt);
buf->~T();
new (buf) T(fn());
}
int main()
{
std::optional<std::mutex> om;
reemplace(om, FuncThatReturnsMutex);
// om = FuncThatReturnsMutex();
}
Breno G.
On Mon, Aug 21, 2023 at 11:16 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:
> The following is currently impossible in C++26:
>
> extern std::mutex FuncThatReturnsMutex(void);
>
> int main(void)
> {
> std::optional<std::mutex> om;
> om = FuncThatReturnsMutex();
> }
>
> It's impossible because a mutex must be either copiable or movable in
> order to assign it to an 'optional'. We have the same problem with
> 'std::variant', 'std::any', and lots of classes in other libraries like
> Boost.
>
> Currently we can write constructors and assignment operators that take:
> • an Lvalue ref
> • an Rvalue ref
>
> What if we had a third kind whose argument must be a prvalue? An
> implementation of 'optional' would look something like as follows:
>
> template <typename T>
> class optional {
> bool bool_has_value = false;
> alignas(T) char unsigned buf[sizeof(T)];
> public:
> optional(T ^^arg) : buf(arg)
> {
>
> }
>
> optional &operator=(T ^^arg) : buf(arg)
> {
> if ( this->bool_has_value )
> {
> static_cast<T*>(static_cast<void*>(&buf))->~T();
> this->bool_has_value = false;
> }
>
> __emplace;
>
> this->bool_has_value = true;
>
> return *this;
> }
> };
>
> In the case of the constructor, if 'FuncThatReturnsMutex' throws an
> exception, then the 'optional' constructor as a whole will throw an
> exception, so no problem there.
>
> But in the case of the assignment operator, we have a problem if
> 'FuncThatReturnsMutex' throws, so we need control over when the prvalue
> gets generated -- and that's why I have the '__emplace' keyword there.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2023-08-21 14:33:04