4
votes

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4553.pdf

gcc6: -fconcepts

template<typename T>
concept bool String = requires(T s)
{
    { s.clear() } -> void;
    // etc.
};

void print(const String& message);
//void print(Str message); // I want Str = const String&

void test()
{
  std::string str;
  print(str);
}

Is there any way to declare Str as const String&?

1
Maybe it's possible, but I wouldn't recommend hiding things like that. If I see a parameter with type Str I will assume that it creates a copy rather than secretly taking a reference.TartanLlama
This code is just an example. I want to know if it could be done, not whether this particular example makes any sense.Boris Rasin
You could do something like template <String T> using Str = const T&;, but then you don't get the deduction.TartanLlama
This makes no sense. It will not allow to declare abbreviated template "void print(Str message);" as requested.Boris Rasin
That's why I said you don't get the deduction with methods like that. You need the template deduction to carry out the pattern matching on const T&.TartanLlama

1 Answers

2
votes

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.