std::basic_osyncstream
's move assignment operator be noexcept
?Section: 31.11.3.1 [syncstream.osyncstream.overview] Status: C++23 Submitter: Jiang An Opened: 2023-01-29 Last modified: 2023-11-22
Priority: Not Prioritized
View all other issues in [syncstream.osyncstream.overview].
View all issues with C++23 status.
Discussion:
The synopsis of std::basic_osyncstream
(31.11.3.1 [syncstream.osyncstream.overview]) indicates that it's
member functions behave as if it hold a std::basic_syncbuf
as its subobject, and according to
16.3.3.4 [functions.within.classes], std::basic_osyncstream
's move assignment operator should call
std::basic_syncbuf
's move assignment operator.
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.
Modify 31.11.3.1 [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> { public: […] using syncbuf_type = basic_syncbuf<charT, traits, Allocator>; […] // assignment basic_osyncstream& operator=(basic_osyncstream&&)noexcept; […] private: syncbuf_type sb; // exposition only }; }