https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114387
Bug ID: 114387 Summary: Explicitly declared destructor makes basic_format_context sometimes not movable Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following code snippet doesn't compile when using libstdc++ (https://godbolt.org/z/x3v44PTbq). ``` #include <cstddef> #include <concepts> #include <iterator> #include <format> template<class CharT> class sealed_output_iterator { private: CharT* p_; public: using difference_type = std::ptrdiff_t; explicit sealed_output_iterator(CharT* p) noexcept : p_{p} {} sealed_output_iterator(sealed_output_iterator&&) = default; sealed_output_iterator& operator=(sealed_output_iterator&&) = default; CharT& operator*() const noexcept { return *p_; } sealed_output_iterator& operator++() noexcept { ++p_; return *this; } sealed_output_iterator& operator++(int) noexcept { ++p_; return *this; } }; static_assert(std::movable<sealed_output_iterator<char>>); static_assert(!std::copyable<sealed_output_iterator<char>>); static_assert(std::output_iterator<sealed_output_iterator<char>, const char&>); static_assert(std::movable<std::basic_format_context<sealed_output_iterator<char>, char>>); // ! ```' The reason seems to be that the explicitly declared destructor suppresses the implict declaration of move constructor and assignment operator. https://github.com/gcc-mirror/gcc/blob/c4845edfeaf44756ad9672e8d143f1c8f5c4c0f6/libstdc%2B%2B-v3/include/std/format#L3839 Per https://eel.is/c++draft/format.context, it seems that no specialization member functions of basic_format_context is suppressed, so perhaps libstdc++ should remove the explicit declaration of the destructor. However, it's unclear to me whether users are supposed to be able to default-construct/copy/move basic_format_context objects. So it may be wanted to delete copy functions, but this may need an LWG issues.