As an update to this, P2325R3 was just adopted which makes std::ostream_iterator
no longer default constructible (it was briefly made so in C++20).
This follows the Elements of Programming design philosophy of how types should behave. If you've heard the phrase "do as the int
s do", that is that philosophy -- types should be Regular
. And the EoP definition of Regular is:
T’s computational basis includes equality, assignment, destructor, default constructor, copy constructor, total ordering (or default total ordering) and underlying type
which translates to real C++20 concepts as:
template<class T>
concept Movable = is_object_v<T> && MoveConstructible<T> && Assignable<T&, T>
&& Swappable<T>;
template<class T>
concept Copyable = CopyConstructible<T> && Movable<T> && Assignable<T&, const T&>;
template<class T>
concept Semiregular = Copyable<T> && DefaultConstructible<T>;
template<class T>
concept Regular = Semiregular<T> && EqualityComparable<T>;
We've lost the total ordering part in favor of simply EqualityComparable
, and even then a lot of the library requirements via Ranges actually only require Semiregular
- not Regular
. But still, this is the foundation of the idea.
Note that if a type is movable, it already kind of makes sense for it to be default constructible. The moved-from state is very conceptually similar to a default-constructed state. Can't do much from there, but it's a state.
std::ostream_iterator
. – Interpretivestd::ostream_iterator
. That is what this question is asking about. So C++20 seems like a very relevant tag. – Interpretivestd::ostream_iterator
can only be constructed with a stream." So he is explicitly not looking at C++20. – Nealson