首先,我认为这是interface Foo<T, K extends keyof T> {
key: K;
map: (value: T[K]) => any;
}
,但以下事实改变了我的想法。
我尝试使用rvalue
作为表达式,它可以正常工作,但是运算符&(*&a)
只能与&
一起使用,因此lvalue
是(*&a)
,为什么呢?
答案 0 :(得分:1)
此表达式&(&a)
无效,将不起作用。
根据C Stnadard
1一元&运算符的操作数应为一个函数 指示符,是[]或一元*运算符,或左值的结果 指定不是位字段且未声明的对象 和寄存器存储类说明符。
和
3一元&运算符产生其操作数的地址。如果 操作数的类型为“ type”,结果的类型为“ pointer to type”。如果 该操作数是一元*运算符的结果,该运算符都不是 也不对&运算符求值,结果就像两个 省略了,只不过对操作员的约束仍然适用 结果不是左值。
因此,表达式&a
的结果不是左值。因此,您可能无法将运算符&
应用于&&a
之类的表达式。
这是一个演示程序。
#include <stdio.h>
int main(void)
{
int x = 10;
&( &x );
return 0;
}
编译器gcc 8.3发出错误
prog.c: In function ‘main’:
prog.c:7:2: error: lvalue required as unary ‘&’ operand
&( &x );
^
此表达式*&a
有效,结果为左值。
4一元*运算符表示间接。如果操作数指向a 函数,结果是一个函数指示符; 如果它指向一个 对象,结果是一个左值指定对象。如果 操作数的类型为“要输入的指针”,结果的类型为“类型”。如果 无效的值已分配给指针, 一元*运算符未定义。
请记住,括号不影响所包围的表达式是否为左值。
答案 1 :(得分:1)
根据C 2018 6.5.3.2 4(讨论unary *
运算符),一元*
的结果是一个左值:
…如果操作数指向一个函数,则结果为一个函数指示符;否则为0。如果它指向一个对象,则结果是一个指定该对象的左值。……
这告诉我们*&a
是左值。但是,问题中询问的表达式是(*&a)
,因此我们必须考虑括号的作用。
6.3.2.1 2(讨论自动转换)似乎告诉我们(*&a)
转换为*&a
中的值,而不是左值:
除了它是sizeof运算符的操作数之外,一元
&
运算符,++
运算符,--
运算符或.
的左操作数除外运算符或赋值运算符,将不具有数组类型的左值转换为存储在指定对象中的值(不再是左值);这称为左值转换。
但是,6.5.1 5(讨论带括号的表达式)与此矛盾:
带括号的表达式是主要表达式。它的类型和值与非括号表达式相同。如果未加括号的表达式分别是一个左值,一个函数标记或一个空表达式,则它是一个左值,一个函数标记或一个空表达式。
这是C标准的缺陷; 6.5.1 5和6.3.2.1 2相互矛盾。我们需要了解的是,专门针对括号表达式的6.5.1 5优先于更通用的6.3.2.1 2,这就是所有C实现的行为方式。
因此(*&a)
是一个左值。