为什么将表达式转换为rvalue对函数的引用是lvalue?

Ron*_*ang 5 c++ c++11

在这里,cppreference-lvalue,我发现了

将表达式转换为对函数的rvalue引用是lvalue.

我很好奇,所以我进行了以下实验:

#include <iostream>

using namespace std;


typedef void (&&funr) (int);
typedef void (&funl) (int);

void test(int num){
    cout<<num<<endl;//output:20
}

void foo(funr fun){
    fun(10);
}

void foo(funl fun){
    fun(20);//call this
}

template <typename T> void foo(T&& fun){
    cout<<is_same<T,void(&)(int)>::value<<endl;//true, it is lvalue. 
    cout<<is_same<T,void(int)>::value<<endl;//false, it isn't rvalue.
}
int main()
{

   foo(static_cast<void(&&)(int)>(test));
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

这样的事实.

为什么将表达式转换为rvalue对函数的引用是lvalue?是因为函数类型不需要移动语义或其他东西吗?或者我理解这个词错了.

将表达式转换为对函数的rvalue引用是lvalue

Rei*_*ica 8

它遵循C++ 11 3.10/1中的值类别的定义(强调我的):

  • 一个左值(...)表示一函数或一个对象....

  • x值(即"到期"值),也引用了一个对象,...

  • 右值(...)是一个x值,一个临时对象(12.2)或者子对象,或它们的不与一个对象相关联的值.

  • prvalue("纯"右值)是一个rvalue这不是一个x值....

请注意,只有左值类别可以是一个函数,所有其他类别只是值或对象.

它也在5.2.9/1中得到回应:

表达式static_cast<T>(v)的结果是将表达式转换v为type 的结果T.如果T左值引用类型或函数类型的右值引用,则结果为左值 ; if T是对象类型的右值引用,结果是xvalue; 否则,结果是prvalue....

至于它的原因,我当然只能猜测(不是标准化委员会的一部分).但我的猜测是,拥有函数类型的rvalues是没有意义的 - 函数永远不会是临时函数,它永远不会处于或接近其生命周期的末尾.