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.