3867. Should std::basic_osyncstream's move assignment operator be noexcept?

Section: [syncstream.osyncstream.overview] Status: C++23 Submitter: Jiang An Opened: 2023-01-29 Last modified: 2023-11-22 15:57:15 UTC

Priority: Not Prioritized

View all other issues in [syncstream.osyncstream.overview].

View all issues with C++23 status.


The synopsis of std::basic_osyncstream ( [syncstream.osyncstream.overview]) indicates that it's member functions behave as if it hold a std::basic_syncbuf as its subobject, and according to [functions.within.classes], std::basic_osyncstream's move assignment operator should call std::basic_syncbuf's move assignment operator.

However, currently std::basic_osyncstream's move assignment operator is noexcept, while std::basic_syncbuf's is not. So when an exception is thrown from move assignment between std::basic_syncbuf objects, std::terminate should be called.

It's clarified in LWG 3498 that an exception can escape from std::basic_syncbuf's move assignment operator. Is there any reason that an exception shouldn't escape from std::basic_osyncstream's move assignment operator?

[2023-02-06; Reflector poll]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4928.

  1. Modify [syncstream.osyncstream.overview] as indicated:

    namespace std {
      template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
      class basic_osyncstream : public basic_ostream<charT, traits> {
        using syncbuf_type = basic_syncbuf<charT, traits, Allocator>;
        // assignment
        basic_osyncstream& operator=(basic_osyncstream&&) noexcept;
        syncbuf_type sb; // exposition only