This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
Section: 31 [input.output] Status: C++20 Submitter: Tim Song Opened: 2018-06-30 Last modified: 2021-02-25
Priority: 0
View all other issues in [input.output].
View all issues with C++20 status.
Discussion:
There are 27 instances of &sb and one instance of &rhs in Clause 31 [input.output], each of which needs to use addressof because the operand has a user-provided template type parameter as an associated class and so the use of unary & is subject to ADL hijacking.
[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]
[2018-11, Adopted in San Diego]
Proposed resolution:
This wording is relative to N4750.
Change 31.5.4.3 [basic.ios.members] p16 as indicated:
basic_ios& copyfmt(const basic_ios& rhs);-16- Effects: If (this ==
&addressof(rhs)) does nothing. […]
Change 31.8.3.2 [istringstream.cons] as indicated:
explicit basic_istringstream(ios_base::openmode which);-1- Effects: Constructs an object of class basic_istringstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(
&addressof(sb)) (31.7.5.2 [istream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(which | ios_base::in) (31.8.2.2 [stringbuf.cons]).explicit basic_istringstream( const basic_string<charT, traits, Allocator>& str, ios_base::openmode which = ios_base::in);-2- Effects: Constructs an object of class basic_istringstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(
&addressof(sb)) (31.7.5.2 [istream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(str, which | ios_base::in) (31.8.2.2 [stringbuf.cons]).basic_istringstream(basic_istringstream&& rhs);-3- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_stringbuf. Next basic_istream<charT, traits>::set_rdbuf(
&addressof(sb)) is called to install the contained basic_stringbuf.
Change 31.8.3.4 [istringstream.members] p1 as indicated:
basic_stringbuf<charT, traits, Allocator>* rdbuf() const;-1- Returns: const_cast<basic_stringbuf<charT, traits, Allocator>*>(
&addressof(sb)).
Change 31.8.4.2 [ostringstream.cons] as indicated:
explicit basic_ostringstream(ios_base::openmode which);-1- Effects: Constructs an object of class basic_ostringstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(
&addressof(sb)) (31.7.6.2 [ostream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(which | ios_base::out) (31.8.2.2 [stringbuf.cons]).explicit basic_ostringstream( const basic_string<charT, traits, Allocator>& str, ios_base::openmode which = ios_base::out);-2- Effects: Constructs an object of class basic_ostringstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(
&addressof(sb)) (31.7.6.2 [ostream]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(str, which | ios_base::out) (31.8.2.2 [stringbuf.cons]).basic_ostringstream(basic_ostringstream&& rhs);-3- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_stringbuf. Next basic_ostream<charT, traits>::set_rdbuf(
&addressof(sb)) is called to install the contained basic_stringbuf.
Change 31.8.4.4 [ostringstream.members] p1 as indicated:
basic_stringbuf<charT, traits, Allocator>* rdbuf() const;-1- Returns: const_cast<basic_stringbuf<charT, traits, Allocator>*>(
&addressof(sb)).
Change 31.8.5.2 [stringstream.cons] as indicated:
explicit basic_stringstream(ios_base::openmode which);-1- Effects: Constructs an object of class basic_stringstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(
&addressof(sb)) (31.7.5.7.2 [iostream.cons]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(which).explicit basic_stringstream( const basic_string<charT, traits, Allocator>& str, ios_base::openmode which = ios_base::out | ios_base::in);-2- Effects: Constructs an object of class basic_stringstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(
&addressof(sb)) (31.7.5.7.2 [iostream.cons]) and initializing sb with basic_stringbuf<charT, traits, Allocator>(str, which).basic_stringstream(basic_stringstream&& rhs);-3- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_stringbuf. Next basic_istream<charT, traits>::set_rdbuf(
&addressof(sb)) is called to install the contained basic_stringbuf.
Change 31.8.5.4 [stringstream.members] p1 as indicated:
basic_stringbuf<charT, traits, Allocator>* rdbuf() const;-1- Returns: const_cast<basic_stringbuf<charT, traits, Allocator>*>(
&addressof(sb)).
Change 31.10.3.2 [ifstream.cons] as indicated:
basic_ifstream();-1- Effects: Constructs an object of class basic_ifstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(
&addressof(sb)) (31.7.5.2.2 [istream.cons]) and initializing sb with basic_filebuf<charT, traits>() (31.10.2.2 [filebuf.cons]).explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in); // wide systems only; see 31.10.1 [fstream.syn]-2- Effects: Constructs an object of class basic_ifstream<charT, traits>, initializing the base class with basic_istream<charT, traits>(
&addressof(sb)) (31.7.5.2.2 [istream.cons]) and initializing sb with basic_filebuf<charT, traits>() (31.10.2.2 [filebuf.cons]), then calls rdbuf()->open(s, mode | ios_base::in). If that function returns a null pointer, calls setstate(failbit).[…]
basic_ifstream(basic_ifstream&& rhs);-4- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_filebuf. Next basic_istream<charT, traits>::set_rdbuf(
&addressof(sb)) is called to install the contained basic_filebuf.
Change 31.10.3.4 [ifstream.members] p1 as indicated:
basic_filebuf<charT, traits>* rdbuf() const;-1- Returns: const_cast<basic_filebuf<charT, traits>*>(
&addressof(sb)).
Change 31.10.4.2 [ofstream.cons] as indicated:
basic_ofstream();-1- Effects: Constructs an object of class basic_ofstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(
&addressof(sb)) (31.7.6.2.2 [ostream.cons]) and initializing sb with basic_filebuf<charT, traits>() (31.10.2.2 [filebuf.cons]).explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::out); // wide systems only; see 31.10.1 [fstream.syn]-2- Effects: Constructs an object of class basic_ofstream<charT, traits>, initializing the base class with basic_ostream<charT, traits>(
&addressof(sb)) (31.7.6.2.2 [ostream.cons]) and initializing sb with basic_filebuf<charT, traits>() (31.10.2.2 [filebuf.cons]), then calls rdbuf()->open(s, mode | ios_base::out). If that function returns a null pointer, calls setstate(failbit).[…]
basic_ofstream(basic_ofstream&& rhs);-4- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_filebuf. Next basic_ostream<charT, traits>::set_rdbuf(
&addressof(sb)) is called to install the contained basic_filebuf.
Change 31.10.4.4 [ofstream.members] p1 as indicated:
basic_filebuf<charT, traits>* rdbuf() const;-1- Returns: const_cast<basic_filebuf<charT, traits>*>(
&addressof(sb)).
Change 31.10.5.2 [fstream.cons] as indicated:
basic_fstream();-1- Effects: Constructs an object of class basic_fstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(
&addressof(sb)) (31.7.5.7.2 [iostream.cons]) and initializing sb with basic_filebuf<charT, traits>().explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see 31.10.1 [fstream.syn]-2- Effects: Constructs an object of class basic_fstream<charT, traits>, initializing the base class with basic_iostream<charT, traits>(
&addressof(sb)) (31.7.5.7.2 [iostream.cons]) and initializing sb with basic_filebuf<charT, traits>(), then calls rdbuf()->open(s, mode). If that function returns a null pointer, calls setstate(failbit).[…]
basic_fstream(basic_fstream&& rhs);-4- Effects: Move constructs from the rvalue rhs. This is accomplished by move constructing the base class, and the contained basic_filebuf. Next basic_istream<charT, traits>::set_rdbuf(
&addressof(sb)) is called to install the contained basic_filebuf.
Change 31.10.5.4 [fstream.members] p1 as indicated:
basic_filebuf<charT, traits>* rdbuf() const;-1- Returns: const_cast<basic_filebuf<charT, traits>*>(
&addressof(sb)).
Change 31.11.3.1 [syncstream.osyncstream.overview], class template basic_osyncstream synopsis, as indicated:
[Drafting note: The text shown below assumes the application of the proposed resolution of issue 3127.]
namespace std { template<class charT, class traits, class Allocator> class basic_osyncstream : public basic_ostream<charT, traits> { public: […] // 31.11.3.3 [syncstream.osyncstream.members], member functions void emit(); streambuf_type* get_wrapped() const noexcept; syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(&addressof(sb)); } […] }; }
Change 31.11.3.2 [syncstream.osyncstream.cons] p1 and p4 as indicated:
basic_osyncstream(streambuf_type* buf, const Allocator& allocator);-1- Effects: Initializes sb from buf and allocator. Initializes the base class with basic_ostream<charT, traits>(
-2- […] -3- […]&addressof(sb)).basic_osyncstream(basic_osyncstream&& other) noexcept;-4- Effects: Move constructs the base class and sb from the corresponding subobjects of other, and calls basic_ostream<charT, traits>::set_rdbuf(
-5- […]&addressof(sb)).