offa / scope-guard

Implementation of Scoped Guards and Unique Resource as proposed in P0052.
MIT License
46 stars 6 forks source link

unique_resource with non-noexcept resource/deleter move operations fails to build #170

Closed hoosierc closed 3 years ago

hoosierc commented 3 years ago

Hi, and thank you for this implementation!

I've been playing around with it a little bit and found what seems to be a bug, but I'm not familiar enough with templates or this implementation to know whether I'm possibly using it incorrectly (or which fix is appropriate, if it is a bug).

I've found that when using a unique_resource with resource/deleter move operations that are not noexcept, I hit a build error since detail::Wrapper does not have a copy constructor and we don't .get() the value out of the other wrapper when we can't use std::move.

https://godbolt.org/z/9Px1Ec is a somewhat-minimal reproduction of the issue I'm seeing (based on the head of master). By removing either/both of the "noexcept" values on lines 715-716, it will generate errors in the unique_resource move assignment. I've found that I can get things building by adding .get() calls or by adding a copy constructor to detail::Wrapper, but I'm not sure which approach is better.

If I'm just using it incorrectly and no change is necessary, I'm sorry for the false bug report! :)

offa commented 3 years ago

Thanks for reporting! I can reproduce the issue using your example on GCC and Clang. From a first look into P0052 your example should compile.

I was able to compile the code with all combinations of noexcept / not-noexcet by providing a copy-overload for Wrapper::reset(), used in unique_resource's move-assignement operator:

void reset(const Wrapper<T>& newValue) noexcept(std::is_nothrow_assignable_v<T, const T&>)
{
    value = newValue.value;
}

Moreover, it seems there are some test cases missing …