C++20 and C++23 introduce template constructors for iterator pairs and ranges for std::string_view
. std::span
has analogous constructors.
template<class It, class End>
constexpr basic_string_view(It first, End last); // C++20
template<class R>
explicit constexpr basic_string_view(R&& r); // C++23
The documentation contains the requirements for the arguments. Why are these requirements not defined as C++20 concept constraints? Wouldn't that lead to much better error messages?
The standard library specification predates concepts... by a lot. As such, it has its own approach to specifying how things need to behave. The goal of the specification is to make the semantics as clear as possible - rather than enforcing a particular technology choice. The language is constantly changing, so putting in specific choices in the specification is fairly unhelpful.
The way constraints on a standard library function template are spelled out is using a Constraints clause. For that string_view
constructor, for instance, we get:
Constraints:
It
satisfiescontiguous_iterator
.End
satisfiessized_sentinel_for<It>
.is_same_v<iter_value_t<It>, charT>
istrue
.is_convertible_v<End, size_type>
isfalse
.
This'll surely be implemented using concepts and a requires
clause (two of these things are concepts, after all), but the goal of the specification is to simply state what the constraints are, rather than how they will be evaluated. And this, pretty clearly, does that.
Before C++20, would you have wanted to see std::enable_if
in the specification? Obviously not. Likewise, we don't have a Contracts language feature yet, but standard library functions do still have preconditions and postconditions - so those are laid out similarly in Preconditions and Postconditions clauses. When we get Contracts, those won't change, even if the implementations of them do.
See also Walter Brown's paper which clarified a lot of how standard library wording is done - splitting up the one Requires clause we used to have into Constraints (to remove from overload resolution) and Mandates (to issue a diagnostic).
There is a notable exception to this rule - where there are many standard library algorithms which are specified using concepts, specifically. This is for two reasons: either (1) they specifically need the guarantees for overload resolution that concepts provide or (2) they use concepts to additionally bring in other semantic requirements on the algorithm (since concepts have both syntactic and semantic requirements). If neither of these hold (as is the case for the string_view
and span
constructors asked about in the question), there isn't any specific motivation to use concepts - so a Constraints clause is sufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With