You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++中函数名被归类为L-value表达式?

为什么C++中函数名是L-value却无法赋值?

根据Christopher Strachey在指称语义学中的理论,编程语言里的名称会绑定到可绑定值,这可以用函数environment: Id -> D来表示——Id是标识符(名称),D是指称(可绑定值)。如果语言支持赋值,名称指代的可赋值值能在词法作用域内通过赋值改变,但存储值的位置是固定的。为了保持环境的静态性,只有位置会被当作可绑定值(也就是D包含位置类型L,但不包含存储值类型V),而关联位置和存储值的动态关系由state: L -> V表示,其中L是位置(即L-value),V是存储值(即R-value)。

在C++里,函数名不能被赋值,说明它们并不指代位置:函数值F不属于V,而是属于D(也就是D = L + F + …)。比如这段代码:

void f();  // 绑定函数名f
void g();  // 绑定函数名g

int main() {
    f = g;  // 赋值操作失败
    return 0;
}

用命令clang++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out编译时会报错:

main.cpp:5:7: error: non-object type 'void ()' is not assignable
    f = g;  // assignment fails
    ~ ^
1 error generated.

但根据C++标准的定义,函数名属于lvalue表达式:

  • glvalue:求值后能确定某个对象或函数标识的表达式。
  • prvalue:用于初始化对象、计算操作数的值,或是类型为cv void的表达式。
  • xvalue:一种glvalue,指代可复用资源的对象(通常是生命周期即将结束的对象)。
  • lvalue:不是xvalue的glvalue。
  • rvalue:prvalue或xvalue。

那为什么函数名不能赋值、不指代位置,却被归类为lvalue?

关键在于C++的lvalue定义和Strachey理论中的“位置(L-value)”不是完全等价的概念:

  • C++中的glvalue核心是标识确定性——只要表达式能明确指向一个唯一的实体(不管是对象还是函数),它就是glvalue。函数有唯一的标识,所以函数名是glvalue。
  • 而xvalue仅针对对象,函数不属于对象范畴,所以函数名不是xvalue,自然就被归类为lvalue。
  • 赋值操作要求的是可修改的lvalue(modifiable lvalue),但函数名是不可修改的lvalue——C++不允许修改函数名的绑定关系,也不能给函数本身赋值,所以赋值操作会失败。

简单来说:C++的lvalue是“能确定标识的表达式”,而不是“可赋值的位置”,函数名满足前者但不满足后者,所以会出现这种看似矛盾的情况。

内容的提问来源于stack exchange,提问作者Géry Ogam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 11:49:58