istreambuf_iterator(basic_streambuf<charT, traits>* s)
effects unclear when s
is 0
Section: 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_iterator
that uses thestreambuf_type
object*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
s
is a null pointer, constructs an end-of-stream iterator; otherwise initializessbuf_
withs
and constructs anistreambuf_iterator
that uses thestreambuf_type
object*sbuf_
.istreambuf_iterator(const proxy& p) noexcept;-3- Effects: Initializes
sbuf_
withp.sbuf_
and constructs anistreambuf_iterator
that uses thestreambuf_type
object*sbuf_
Constructs a.istreambuf_iterator<>
that uses thebasic_streambuf<>
object pointed to by theproxy
object'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_iterator
constructor 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_
withnullptr
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: 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 theproxy
object's constructor argumentp