N2976 suggested adding constexpr
to some spots in the standard library. It notes that iostream
s are inappropriate for constexpr
EXCEPT end iterators. So istream_iterator
and istreambuf_iterator
were given constexpr
default constructors and that's about it. For example, you can see in the libstdc++ implementation that constexpr
only appears once in the entire file. The LWG that sparked this change was #1129. It says:
istream_iterator
andistreambuf_iterator
should support literal sentinel values. The default constructor is frequently used to terminate ranges, and could easily be a literal value foristreambuf_iterator
, andistream_iterator
when iterating value types. [Rest omitted]
This doesn't make a whole lot of sense to me. Can someone show me an example of what they mean?
N3308 is another paper that mentions but doesn't explain the issue:
Some of the
istream_iterator<T>
constructors are required to beconstexpr
ifT
is a literal type. The intention is to allow existing implementation technique of storing a type ofT
inline to continue to work. [libstdc++ does this,_Tp _M_value
] However, it actually rules out this technique: the default and copy constructors ofT
need not be markedconstexpr
, and if they are not, theistream_iterator<T>
constructors could not be instantiated asconstexpr
.
The above explains the trivial copy constructor and destructor, but not why the default constructor is marked constexpr.
Furthermore, testing on online GCC 5.2.0, I copied libstdc++'s implementation. The only change is I removed constexpr from istream_iterator()
. In both cases, the assemblies are identical.
while (iter != istream_iterator())
. Having that as aconstexpr
might save us a nanosecond or two in the loop. – Blainconstexpr
if only the end iterator can beconstexpr
? (Also I don't believe "save us a nanosecond or two" would justify a defect, a paper, and then library implementators thinking it's worth development time) – Marylynnmarylynneconstexpr
(and that wouldn't work as a loop condition anyway), but comparingiter
to a constant might be cheaper than comparing to something else. – Blainconstexpr
to allow constant initialization in a static initialization phase? can non-static-storage-duration temporary local objects be statically initialized? – Wilfordconstexpr
just might help the compiler with the figure-out-part. In this particular case, I believe most optimizers noticed thatistream_iterator()
produced a constant, even before it was madeconstexpr
. So it is not an important change in the library. – Blainconstexpr
will produce identical assemblies. Again I remain unconvinced that this microoptimization is the true reason. – Marylynnmarylynneconstexpr
was introduced, someone produced a list of things in the standard library that could be madeconstexpr
. In this case, the change is extremely easy to do, doesn't break any old code, and if it has any effect on performance, at least it will not be negative. So, why not? – Blainstd::mutex
constexpr will solve the static initialization (#828) issue, but that's the only issue listed in N2976 that mentions static initialization. I believe the issue is related to makingistream_iterator
a literal type, like most of the other issues. However I'm having trouble connecting the dots. – Marylynnmarylynneistream_iterator
constexpr in both cases. – Marylynnmarylynne