Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does a universal reference in a requires expression actually mean?

This is an example of a concept from cppreference:

template<class T, class U = T>
concept Swappable = requires(T&& t, U&& u)
{
    swap(std::forward<T>(t), std::forward<U>(u));
    swap(std::forward<U>(u), std::forward<T>(t));
};

What does the T&& t parameter mean? Is it a universal reference?

Documentation says:

A requires expression can introduce local parameters using a parameter list. These parameters have no linkage, storage, or lifetime; they are only used as notation for the purpose of defining requirements.

So, what is the actual type of t? Does it mean that the compiler will check lvalue T, lvalue reference T&, and rvalue reference T&& one by one? Or is T&& t not a universal reference, it just serves for reference collapsing (for actual types that could be an lvalue reference)?

like image 923
Mugnus Daisy Avatar asked Aug 31 '25 03:08

Mugnus Daisy


1 Answers

What does this T&& t parameter mean? Is it a universal reference?

No, it's not a universal (forwarding) reference. A forwarding reference is only in the specific case where you have a deduced parameter of type T&&. That's not the case here — nothing is deduced.

For Swappable<int>, t and u are of type int&&. For Swappable<int&>, they are both of type int&.

Similar to:

template <class T>
struct X {
    void f(T&& t);

    template <class U>
    void g(U&& u);
};

u is a forwarding reference, t is not.

like image 167
Barry Avatar answered Sep 02 '25 17:09

Barry