This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.
istreambuf_iterator(basic_streambuf<charT, traits>* s) effects unclear when s is 0Section: 24.6.4.3 [istreambuf.iterator.cons] Status: C++17 Submitter: S. B. Tam Opened: 2015-10-05 Last modified: 2017-07-30
Priority: 3
View all issues with C++17 status.
Discussion:
N4527 24.6.4.3 [istreambuf.iterator.cons] does not mention what the effect of calling
istreambuf_iterator(basic_streambuf<charT, traits>* s) is when s is a null pointer.
It should be made clear that this case is well-formed and the result is a end-of-stream iterator.
[…] The default constructor
istreambuf_iterator()and the constructoristreambuf_iterator(0)both construct an end-of-stream iterator object suitable for use as an end-of-range. […]
This indicates that the described constructor creates an end-of-stream iterator, but this wording is part of the introductory
wording and I recommend to make 24.6.4.3 [istreambuf.iterator.cons] clearer, because the existing specification is already
flawed, e.g. it never specifies when and how the exposition-only-member sbuf_ is initialized. The proposed wording
below attempts to solve these problems as well.
Previous resolution [SUPERSEDED]:
This wording is relative to N4527.
Change 24.6.4.3 [istreambuf.iterator.cons] as indicated:
[Editorial note: The proposed wording changes also performs some editorial clean-up of the existing mismatches of the declarations in the class template synopsis and the individual member specifications. The below wording intentionally does not say anything about the concrete value ofsbuf_for end-of-stream iterator values, because that was never specified before; in theory, this could be some magic non-null pointer that can be used in constant expressions. But the wording could be drastically simplified by requiringsbuf_to be a null pointer for an end-of-stream iterator value, since I have not yet seen any implementation where this requirement does not hold. — end editorial note]constexpr istreambuf_iterator() noexcept;-1- Effects: Constructs the end-of-stream iterator.
istreambuf_iterator(basic_istream<charT,traits>istream_type& s) noexcept;istreambuf_iterator(basic_streambuf<charT,traits>* s) noexcept;-2- Effects: If
s.rdbuf()is a null pointer, constructs an end-of-stream iterator; otherwise initializessbuf_withs.rdbuf()and constructs anistreambuf_iteratorthat uses thestreambuf_typeobject*sbuf_Constructs an.istreambuf_iterator<>that uses thebasic_streambuf<>object*(s.rdbuf()), or*s, respectively. Constructs an end-of-stream iterator ifs.rdbuf()is nullistreambuf_iterator(streambuf_type* s) noexcept;-?- Effects: If
sis a null pointer, constructs an end-of-stream iterator; otherwise initializessbuf_withsand constructs anistreambuf_iteratorthat uses thestreambuf_typeobject*sbuf_.istreambuf_iterator(const proxy& p) noexcept;-3- Effects: Initializes
sbuf_withp.sbuf_and constructs anistreambuf_iteratorthat uses thestreambuf_typeobject*sbuf_Constructs a.istreambuf_iterator<>that uses thebasic_streambuf<>object pointed to by theproxyobject's constructor argumentp
[2015-10-20, Daniel provides alternative wording]
[2016-08-03 Chicago]
Fri AM: Moved to Tentatively Ready
Proposed resolution:
This wording is relative to N4606.
Change 24.6.4.3 [istreambuf.iterator.cons] as indicated:
[Drafting note: The proposed wording changes also performs some editorial clean-up of the existing mismatches of the declarations in the class template synopsis and the individual member specifications. The below wording is simplified by requiring
sbuf_to be a null pointer for an end-of-stream iterator value, since I have not yet seen any implementation where this requirement does not hold. Even if there were such an implementation, this would still be conforming, because concrete exposition-only member values are not part of public API. — end drafting note]
For each
istreambuf_iteratorconstructor in this section, an end-of-stream iterator is constructed if and only if the exposition-only membersbuf_is initialized with a null pointer value.constexpr istreambuf_iterator() noexcept;-1- Effects: Initializes
sbuf_withnullptrConstructs the end-of-stream iterator.istreambuf_iterator(basic_istream<charT,traits>istream_type& s) noexcept;istreambuf_iterator(basic_streambuf<charT,traits>* s) noexcept;-2- Effects: Initializes
sbuf_withs.rdbuf()Constructs an.istreambuf_iterator<>that uses thebasic_streambuf<>object*(s.rdbuf()), or*s, respectively. Constructs an end-of-stream iterator ifs.rdbuf()is nullistreambuf_iterator(streambuf_type* s) noexcept;-?- Effects: Initializes
sbuf_withs.istreambuf_iterator(const proxy& p) noexcept;-3- Effects: Initializes
sbuf_withp.sbuf_Constructs a.istreambuf_iterator<>that uses thebasic_streambuf<>object pointed to by theproxyobject's constructor argumentp