重值引用不是将类型和类别混合在一起吗?
Doesn't rvalue reference mix together type and category?
这篇文章反映了我目前对价值类别的理解水平。
值类别是表达式的属性。 类型是变量的属性。
假设我们有以下声明:
int x;
什么是 x?它是一个变量,它是一个表达式。
编写如下新语法:
int&& ref
而不是
int& ref
让人们认为我们做了一些与类型相关的事情,但实际上我们做了一些与表达式相关的事情,而不是类型。(我们已经指定了哪些表达式可以绑定到这些变量。
可能区分"临时">和"非临时"可以用另一种方式完成,也许是这样的:
void func(int&); // for "non-temporaries"
void func((int&)); // for "temporaries
或其他方式,但不摆弄类型。
所以我的问题是: 是否有必要将有关表达式类别的信息编码为类型的语法?做出此设计决定的原因是什么?
右值引用是与左值引用不同的类型,因此它们可以对某些内容进行编码:用户创建该引用时的特定意图。如果进行右值引用,则特别希望可以从中移动它引用的对象。这是与使用左值引用不同的意图。
仅使用名称无法检测到该特定意图;右值引用变量的值类别是左值。但是可以从类型中检测到该意图。类型很重要。
我们希望能够在这个声明的意图上重载函数,让一个重载可以接受一个可以移动的对象,而另一个不能。这是区分复制构造函数和移动构造函数的基础。C++基于类型的重载函数,因此...我们必须在类型级别指定此意图。
在func
示例中,如果int&
和(int&)
是同一类型,则根据当前存在的C++规则,这两个func
函数声明相同的函数。因此,您需要发明新的规则,将"函数签名"的概念定义为不仅仅是所涉及的类型。您必须弄乱重载解析才能确定调用哪个函数。等。
另外,std::move
工作(即,返回值可以绑定到右值引用),因为右值引用类型的返回值的值类别被定义为 xvalue。xvalues 可以绑定到右值引用。按照您的方式,此(&)
语法必须具有类似的属性。但它不能基于类型,因为根据定义,它不会更改类型。因此,从本质上讲,您必须声明引用类型可以在类型旁边包含此额外的非类型信息。此信息不能由任何普通接口查询,这与表达式的类型信息不同,表达式的类型信息可以通过decltype
查询。
或者,您可以创建一个新类型并免费获得其中的大部分。您仍然需要研究重载解析如何适用于此新类型,并且仍然必须定义 rvalue 引用绑定规则,但函数签名的概念保持不变,并且您不需要位于类型旁边的这个尴尬的额外信息通道。
为此意图使用引用还允许引用折叠规则,这是"完美"转发的基础:能够编写单个(模板)函数,该函数将任何值类别的表达式转发到目标,以保持目标是否可以复制/移动
的方式。- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 将图形属性与 std::unique_ptr 捆绑在一起
- 你能在 c++ 中将不同的数字类型加在一起吗?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 为什么push_back和emplace_back结合在一起时,会有不同的行为
- 将C++与C混合在预制块中4
- 在浮点精度成为一个问题之前,可以将多少个浮点值加在一起
- 在 c++ 中,两个日志行与 log4Cxx 混合在一起
- 有没有一种干净(更)的方法将 CRTP 与可变参数继承混合在一起?
- 重值引用不是将类型和类别混合在一起吗?
- 通用设计与奇怪的重复模板模式混合在一起.C++
- 将构造函数与固定参数混合,将构造函数与构造函数模板混合在一起
- 将命令模式,工厂模式和模板混合在一起..
- 将泛型编程与多态性混合在一起
- 将两个数组混合在一起
- C++将unqiue_ptr与同一对象的原始指针混合在一起
- drawinstance和DrawIndexed并将它们混合在一起
- 将函数代码与预处理器指令混合在一起是不是一种糟糕的做法
- Photoshop如何将两个图像混合在一起