这一员额反映了我目前对价值类别的理解程度。
值类别是表达式的属性。类型是变量的一部分。
假设我们有以下声明:
int x;什么是x?它是一个变量,也是一个表达式。
编写如下新语法:
int&& ref而不是
int& ref让人们认为我们做了一些与类型有关的事情,但实际上我们做了一些与表达有关的事情,而不是类型。(我们已经指定了可以绑定到这些变量的表达式。)
区分“临时人员”和“非临时人员”可能是另一种方式,也许是这样的:
void func(int&); // for "non-temporaries"
void func((int&)); // for "temporaries或者其他方式,但不是摆弄类型。
因此,我的问题是:是否有必要将有关表达式类别的信息编码到类型的语法中?这个设计决定的原因是什么?
发布于 2019-05-25 15:49:41
Rvalue引用是与lvalue引用不同的类型,因此它们可以编码某些内容:用户在创建引用时的特定意图。如果您进行了一个rvalue引用,那么您特别希望可以将其引用的对象从其中移除。这是与使用lvalue引用不同的意图。
不能仅从名称的使用中检测到特定的意图;rvalue引用变量的值类别是lvalue。但这种意图是可以从这种类型中检测出来的。类型很重要。
我们希望能够在这个声明的意图上重载函数,一个重载可以从一个对象中移动,另一个不能,这是复制构造函数和移动构造函数之间区别的基础。C++基于类型重载函数,所以..。我们必须在类型级别指定此意图。
在func示例中,如果int&和(int&)是相同的类型,那么按照当前存在的C++规则,这两个func函数都声明相同的函数。因此,您需要发明新的规则,将“函数签名”的概念定义为不仅仅是所涉及的类型。您必须处理重载解析,以确定调用哪个函数。等。
此外,std::move工作(即返回值可以绑定到rvalue引用),因为rvalue引用类型的返回值的值类别被定义为xvalue。并且rvalue可以绑定到rvalue引用。按照您的方式,这个(&)语法必须具有类似的属性。但是它不能基于类型,因为根据定义,它不会改变类型。所以在本质上,你必须声明引用类型可以有这个额外的,非类型的,信息坐在一个类型旁边。与decltype可以查询的表达式的类型信息不同,任何普通接口都不能查询此信息。
或者你可以创建一个新的类型,并且免费获得其中的大部分。您仍然需要研究这种新类型的重载解析是如何工作的,您仍然需要定义rvalue引用绑定规则,但是函数签名的概念没有改变,并且您不需要在类型旁边的这个尴尬的额外信息通道。
对此意图使用引用还允许引用-折叠规则,这是“完美”转发的基础:编写单个(模板)函数,将任何值类别的表达式转发给目的地,从而保证目标是否可以复制/移动。
https://stackoverflow.com/questions/56306144
复制相似问题