为什么我不能将左值引用绑定到右值,而概念可以?

Why can't I bind an lvalue-reference to an rvalue while a concept can?

#include <utility>

template<typename T>
concept IsWritable = requires(T& obj)
{
    obj = 0;
};

template<typename T>
void f(T&)
{}

int main()
{
    static_assert(IsWritable<int&&>); // ok
    
    int n = 0;
    f(std::move(n)); // error
}

GCC 错误信息:

error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 
       'std::remove_reference<int&>::type' {aka 'int'}

为什么我不能将左值引用绑定到右值,而概念可以?

给定

template<typename T>
void f(T&)
{}

    f(std::move(n)); // error

一定会出错,因为您正试图将右值参数 std::move(n) 传递给左值引用参数 T&.

关于概念,请注意值级别 上没有参数-参数对。正是在 价值水平 上,谈论 rvalue/lvalue-ness 才有意义(毕竟,那些被称为 value categories)。

虽然在类型级别上有一个参数-参数对:您明确地将 int&& 模板参数 传递给 IsWritable模板参数 T,所以 T& 将是 int&& &,也就是 int&,因为正常的引用 collpasing 适用(它不仅适用于通用引用)。