I looked recently at this video explaining the ideas of concepts lite in C++, which are likely to appear this year as a TS. Now, I also learned about universal references/forwarding references (as described here) and that T&& can have two meanings depending on the context (i.e. if type deduction is being performed or not). This leads naturally to the question how concepts will interact with universal references?
To make it concrete, in the following example we have
void f(int&& i) {}
int i = 0;
f(i); // error, looks for f(int&)
f(0); // fine, calls f(int&&)
and
template <typename T>
void f(T&& test) {}
int i = 0;
f(i); // fine, calls f(T&&) with T = int& (int& && = int&)
f(0); // fine, calls f(T&&) with T = int&& (int&& && = int&&)
But what happens if we use concepts?
template <typename T>
requires Number<T>
void f(T&& test) {}
template <Number T>
void g(T&& test) {}
void h(Number&& test) {}
int i = 0;
f(i); // probably should be fine?
f(0); // should be fine anyway
g(i); // probably also fine?
g(0); // fine anyway
h(i); // fine or not?
h(0); // fine anyway
Especially the last example bothers me a bit, since there are two conflicting principles. First, a concept used in this way is supposed to work just as a type and second, if T is a deduced type, T&& denotes a universal reference instead of an rvalue reference.
Thanks in advance for clarification on this!
T
would beint
, notint&&
– Firedog