On 11/30/23 22:37, Peter Dimov via Boost wrote:
Andrey Semashev wrote:
That's
template
class resource; This would also prohibit resource types with non-constexpr constructors, as well as non-default-constructible resources. I don't like this tradeoff.
It doesn't. The two operations required from R are construction from Def and comparing to Def.
https://godbolt.org/z/h7z3qGzvs
Note that the type of Def doesn't have to be R.
What I meant is something like this won't work:
That's a common objection but the fix is simple:
https://godbolt.org/z/KTM9eb5r8
And if you're suggesting to define some magic placeholder type that can be used as Def and automatically converts to R then that looks like a more contrived usage to me than just defining resource traits.
That's typically not that hard either, although for std::string specifically it doesn't work very well because operator!= is templated. So we're hitting worst case:
constexpr struct invalid_t { operator std::string() const noexcept { return "invalid"; }
Not noexcept, std::string constructor may throw.
friend bool operator!=( std::string const& s, invalid_t ) { return s != "invalid"; } } invalid;
Most of the time it's much simpler, though.
Just for reference, here's how the current implementation would look: struct string_resource_traits { static std::string const& make_default() noexcept { return g_invalid; } static bool is_allocated(std::string const& res) noexcept { return res != g_invalid; } static const std::string g_invalid; }; const std::string string_resource_traits::g_invalid{ "invalid" }; struct string_deleter { void operator()(std::string const& res) noexcept { close(res); } }; using fd = unique_resource< std::string, string_deleter, string_resource_traits
;