Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't string_view and span constructors use C++20 concepts?

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?

like image 648
Benjamin Buch Avatar asked Sep 03 '25 16:09

Benjamin Buch


1 Answers

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 satisfies contiguous_iterator.
  • End satisfies sized_sentinel_for<It>.
  • is_same_v<iter_value_t<It>, charT> is true.
  • is_convertible_v<End, size_type> is false.

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.

like image 165
Barry Avatar answered Sep 05 '25 07:09

Barry