Is there any way to declare Str as const String&?
No. And moreover, you don't want that anyway. Concepts are about adding constraints to types. So if you want to constraint print to take something that models String, you can do that:
template <typename T> requires String<T> void print(T const&); // requires-clause
template <String T> void print(T const&); // partial-concept-id
void print(String auto const&); // probably what C++20 will allow
But the constraint and the value category are orthogonal. You could take String by value:
void print(String auto);
you could take a String by forwarding reference:
void print(String auto&&);
These are all separate options from the "I want a String" aspect. You can't really group those together.
The best you could do is:
template <String T> using Str = T const&;
template <typename T> void print(Str<T>); // silently a const&
or
template <typename T> using CR = T const&;
template <String T> void print(CR<T>); // silently a const&
That works. For some definition of works. But like... don't do that. The fact that a function takes a const& as opposed to a value is very important visual information, don't just hide it.
StrI will assume that it creates a copy rather than secretly taking a reference. - TartanLlamatemplate <String T> using Str = const T&;, but then you don't get the deduction. - TartanLlamaconst T&. - TartanLlama