自相矛盾的引用定义
Contradicting definition of references
我正在学习 C++ 中的引用。特别是,我了解到引用不是实际对象。相反,他们指的是其他一些对象。也就是说,引用只是其他对象的别名。
然后我遇到了 this 上面写着:
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object. There is no C++ syntax that lets you operate on the reference itself separate from the object to which it refers.
我明白上面的引述意味着我们不能对引用本身进行操作,与它所引用的对象分开,但它仍然似乎暗示“一个引用是一个对象。
此外,我遇到了下面给出的句子:
In ISO C++, a reference is not an object. As such, it needs not have any memory representation.
我没有第二个引述的 link,但我在某个 SO 的 post 某处读到了它。
我的问题是,假设第二个引用也来自标准(可能不是这种情况),这两个引用的语句是否相互矛盾。或者至少第一句话是误导性的。哪一个是正确的。
我目前的理解(通过阅读 C++ Primer 第 5 版等书籍)是引用是对象的别名。这让我想到他们不应该在内存中使用任何 space。
第一条引述实际上是在说引用与对象不可分离。
... still seems to imply that "a reference is an object".
这实际上意味着引用是对象的 non-separable、non-first-class 别名,正如您最初所说的那样。
这些讨论的困难在于,“对象”的标准含义已经不同于大多数 less-formal 上下文中使用的含义。
让我们从简单的开始:
int a;
通常会被描述为声明一个整数对象 a
,对吧?实际上
- 声明一个整数对象
- 将名称
a
绑定到适当范围内的对象
现在,如果我们写
int &b = a;
我们可以说 b
是 对象,就像我们可以说 a
是对象一样。实际上两者都不正确,但考虑到非正式文本已经使用了后者,它并不 更糟。
我们应该说名称 b
与名称 a
指的是同一个对象。这与称它为别名完全一致,但非正式或介绍性的文本如果在任何地方都写“......由名称 a
引用的整数对象......”而不仅仅是“整数”,看起来会很麻烦a
".
至于在内存中使用 space ......这取决于。如果我在单个函数中为单个对象引入 100 个别名,如果编译器不只是折叠它们(当然它们可能仍会显示在调试符号中),我会感到非常惊讶。省略冗余名称不会丢失任何信息。
如果我通过对 non-inlined 函数的引用传递参数,一些 实际信息正在传达,并且该信息必须存储在某处。
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. ...
注释是非正式的,通常不应被解释为严格的规则。如果解释与标准规则相矛盾,则该解释是错误的。
引用和对象是不同种类的实体。引用不是与其命名的对象不同的对象。不可能形成指向引用的指针。 “指向引用的指针”甚至不是有效的类型类别。
注释试图说明引用“是”它所命名的对象,即使用引用就是使用被引用的对象。
I was thinking of confirming that whether or not references take any space
参考文献采用 space 或不采用 space。由语言实现来确定在每种情况下是否需要 space。
标准报价:
[dcl.ref] It is unspecified whether or not a reference requires storage
在标准规范之外,如果您想要使用 space 的引用示例,请尝试将引用成员添加到 class,您很可能会观察到 class增加。
since pointers take space then reference should also take space. ...
指针确实在标准指定的抽象机中使用 space。但是,如果您从不观察存储,那么存储实际上根本不存在是完全可能的。引用和指针之间的显着区别是您无法直接观察引用的存储。
哲学家:“如果一棵树倒在一台抽象机器中,而周围没有人观察它,它有影响吗 ?
优化者:“如果我能帮上忙就不会。”
引用实际上“是”什么并没有多大意义:您可以说它是被引用的对象或者它是它的别名,这些说法在某种意义上都是正确的。
int main()
{
int a(0);
int& ref(a);
ref = 1; // Will actually affect the value of a
return 0;
}
让我们逐行分析这个程序。
int a(0);
在堆栈上分配一些内存(通常是 4 个字节)来保存一个整数。
int& ref(a);
不一定分配内存,不管它是否真的会分配内存compiler-specific。从这个意义上说,ref
本身不是一个对象:它只是 a
的一个别名,另一个名称。这就是第二个引用“引用不是对象”的意思。 (请注意,有时,当无法知道在 compile-time 处引用了什么对象时,引用必须为对象的地址保留额外的 space 。在这些情况下,引用只是语法指点糖。)
ref = 1;
将 a
的值设置为 1。从这个意义上说,您可以将 ref
视为与 a
完全相同的对象。 任何“对”引用的操作实际上都会对引用的对象进行操作。这就是第一个引号“它是对象”的意思。
引用提供了另一种引用对象的方式。这在将参数 by reference 传递给函数时特别有用。更正式地说,引用是绑定到 变量 的 别名 ,在这种情况下,包括 匿名临时 [=26] =].
幸运的是我们不需要关心它们是如何实现的。这是编译器的工作,而且技术各不相同。 C++标准不要求它们占用任何内存。
这里是顺便说一句区分引用类型的方法。 Non-separability 实际上更多的是关于不能将引用绑定到任何其他变量。参见
#include <iostream>
#include <type_traits>
int main() {
int a = 0;
int& ref = a;
std::cout << (
std::is_reference<decltype(ref)>::value ? "pay me a bonus\n" : "reformat my hard disk\n"
);
std::cout << (
std::is_reference<decltype(a)>::value ? "pay me a bonus\n" : "reformat my hard disk\n"
);
}
最后请注意,&a
和 &ref
必须始终相同。
我正在学习 C++ 中的引用。特别是,我了解到引用不是实际对象。相反,他们指的是其他一些对象。也就是说,引用只是其他对象的别名。
然后我遇到了 this 上面写着:
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object. There is no C++ syntax that lets you operate on the reference itself separate from the object to which it refers.
我明白上面的引述意味着我们不能对引用本身进行操作,与它所引用的对象分开,但它仍然似乎暗示“一个引用是一个对象。
此外,我遇到了下面给出的句子:
In ISO C++, a reference is not an object. As such, it needs not have any memory representation.
我没有第二个引述的 link,但我在某个 SO 的 post 某处读到了它。
我的问题是,假设第二个引用也来自标准(可能不是这种情况),这两个引用的语句是否相互矛盾。或者至少第一句话是误导性的。哪一个是正确的。
我目前的理解(通过阅读 C++ Primer 第 5 版等书籍)是引用是对象的别名。这让我想到他们不应该在内存中使用任何 space。
第一条引述实际上是在说引用与对象不可分离。
... still seems to imply that "a reference is an object".
这实际上意味着引用是对象的 non-separable、non-first-class 别名,正如您最初所说的那样。
这些讨论的困难在于,“对象”的标准含义已经不同于大多数 less-formal 上下文中使用的含义。
让我们从简单的开始:
int a;
通常会被描述为声明一个整数对象 a
,对吧?实际上
- 声明一个整数对象
- 将名称
a
绑定到适当范围内的对象
现在,如果我们写
int &b = a;
我们可以说 b
是 对象,就像我们可以说 a
是对象一样。实际上两者都不正确,但考虑到非正式文本已经使用了后者,它并不 更糟。
我们应该说名称 b
与名称 a
指的是同一个对象。这与称它为别名完全一致,但非正式或介绍性的文本如果在任何地方都写“......由名称 a
引用的整数对象......”而不仅仅是“整数”,看起来会很麻烦a
".
至于在内存中使用 space ......这取决于。如果我在单个函数中为单个对象引入 100 个别名,如果编译器不只是折叠它们(当然它们可能仍会显示在调试符号中),我会感到非常惊讶。省略冗余名称不会丢失任何信息。
如果我通过对 non-inlined 函数的引用传递参数,一些 实际信息正在传达,并且该信息必须存储在某处。
Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. ...
注释是非正式的,通常不应被解释为严格的规则。如果解释与标准规则相矛盾,则该解释是错误的。
引用和对象是不同种类的实体。引用不是与其命名的对象不同的对象。不可能形成指向引用的指针。 “指向引用的指针”甚至不是有效的类型类别。
注释试图说明引用“是”它所命名的对象,即使用引用就是使用被引用的对象。
I was thinking of confirming that whether or not references take any space
参考文献采用 space 或不采用 space。由语言实现来确定在每种情况下是否需要 space。
标准报价:
[dcl.ref] It is unspecified whether or not a reference requires storage
在标准规范之外,如果您想要使用 space 的引用示例,请尝试将引用成员添加到 class,您很可能会观察到 class增加。
since pointers take space then reference should also take space. ...
指针确实在标准指定的抽象机中使用 space。但是,如果您从不观察存储,那么存储实际上根本不存在是完全可能的。引用和指针之间的显着区别是您无法直接观察引用的存储。
哲学家:“如果一棵树倒在一台抽象机器中,而周围没有人观察它,它有影响吗 ?
优化者:“如果我能帮上忙就不会。”
引用实际上“是”什么并没有多大意义:您可以说它是被引用的对象或者它是它的别名,这些说法在某种意义上都是正确的。
int main()
{
int a(0);
int& ref(a);
ref = 1; // Will actually affect the value of a
return 0;
}
让我们逐行分析这个程序。
int a(0);
在堆栈上分配一些内存(通常是 4 个字节)来保存一个整数。int& ref(a);
不一定分配内存,不管它是否真的会分配内存compiler-specific。从这个意义上说,ref
本身不是一个对象:它只是a
的一个别名,另一个名称。这就是第二个引用“引用不是对象”的意思。 (请注意,有时,当无法知道在 compile-time 处引用了什么对象时,引用必须为对象的地址保留额外的 space 。在这些情况下,引用只是语法指点糖。)ref = 1;
将a
的值设置为 1。从这个意义上说,您可以将ref
视为与a
完全相同的对象。 任何“对”引用的操作实际上都会对引用的对象进行操作。这就是第一个引号“它是对象”的意思。
引用提供了另一种引用对象的方式。这在将参数 by reference 传递给函数时特别有用。更正式地说,引用是绑定到 变量 的 别名 ,在这种情况下,包括 匿名临时 [=26] =].
幸运的是我们不需要关心它们是如何实现的。这是编译器的工作,而且技术各不相同。 C++标准不要求它们占用任何内存。
这里是顺便说一句区分引用类型的方法。 Non-separability 实际上更多的是关于不能将引用绑定到任何其他变量。参见
#include <iostream>
#include <type_traits>
int main() {
int a = 0;
int& ref = a;
std::cout << (
std::is_reference<decltype(ref)>::value ? "pay me a bonus\n" : "reformat my hard disk\n"
);
std::cout << (
std::is_reference<decltype(a)>::value ? "pay me a bonus\n" : "reformat my hard disk\n"
);
}
最后请注意,&a
和 &ref
必须始终相同。