为什么允许通过 const 引用而不是通过普通引用传递 R 值?
Why is it allowed to pass R-Values by const reference but not by normal reference?
下面的程序
void display(const int& a)
{
cout << a ;
}
如果使用像这样的文字调用将会工作
display(5);
但如果没有 const
,它将无法工作。
那么 const
引用如何保持指向 R 值(匿名变量)?
又回到了字面量的定义。文字是常量;例如数字 5 的值永远不会改变,尽管变量可能会从被分配的值 5 更改为另一个值。通过引用传递文字意味着函数可以修改它,根据定义,这是你不能对文字做的事情,这就是为什么语言要求你用 const 修改它。我不认为 C++ 可以修改文字,即使它让你尝试,但它仍然强制执行此约定以提醒程序员文字值不能被修改。
因为文字是常量。 1不能变成2,"abd"
不能变成"edf"
.
如果 C++ 允许您通过非 const
引用获取文字,那么它会:
- 必须允许字面量动态改变它们的含义,允许您将 1 变成 2。
- 希望程序员格外小心,仅通过那些不引用文字的引用来修改值,并在出错时调用未定义的行为。
(1) 会在你的程序中造成混乱,因为 x == 1
可能意味着 "is x equal to 2" 取决于上下文,并且 (2) 是不可能实现的,因为 void display(int& a)
应该如何想知道它是否收到文字引用?
由于这两个选项都没有意义,文字只能通过 const
引用传递。
实际上,从字符串文字到 char*
的弃用转换很好地说明了为什么规则很有意义,尽管它不是引用而是指针。您可以让 char*
指向 "abc"
,但尝试实际利用 char*
的 "modifiability" 属性并修改其中一个 char
元素导致未定义的行为。这使得整个弃用的转换既危险又无用(在非遗留代码中)。
你不会想在语言的所有其他部分遇到这样的麻烦吧?
将任何对象视为 盒子,其中包含一些值,盒子可能有也可能没有名称标签,即盒子 with 名称标签为 variable
,框 没有 名称标签为 literal
。不管有没有名牌,我们有盒子。
Reference
是我们将名称标签添加到我们的盒子的方式。
int a = 5;
int &b = a;
我们的盒子有 两个 个名称标签(里面的值为 5
)。
const int &c = 5;
给你,盒子刚刚命名。
以前从未有过名字的盒子的新名字必须标记为const
。因为盒子里面的值可以通过它的名字来改变,我们不希望它发生(不允许发生)到我们的literal
盒子。
最后一个问题:
how can a const reference keep pointing to an R-Value (anonymous variable)
Here is the answer。 C++ 语言说本地 const 引用将临时值的生命周期延长到包含范围的末尾,但可以节省复制构造的成本(即,如果您改用局部变量)。
右值是一个临时的消逝对象,可以读取但即将被销毁。也是不能留在赋值左边的值(给这种鬼东西赋值怎么理解?)
C++ 有一种非常特殊的方法来处理这种实体。如果你可以通过(非常量)引用传递一个右值,你也可以从函数内部给它赋值。因此,如果要通过引用传递 r 值,则规则必须是 const 引用。
虽然这不是全部事实,因为您确实有 r 值引用(用 &&
表示)。所以,你最终可以操作一个临时对象,但你必须明确声明你真的想这样做,使用右值引用。
下面的程序
void display(const int& a)
{
cout << a ;
}
如果使用像这样的文字调用将会工作
display(5);
但如果没有 const
,它将无法工作。
那么 const
引用如何保持指向 R 值(匿名变量)?
又回到了字面量的定义。文字是常量;例如数字 5 的值永远不会改变,尽管变量可能会从被分配的值 5 更改为另一个值。通过引用传递文字意味着函数可以修改它,根据定义,这是你不能对文字做的事情,这就是为什么语言要求你用 const 修改它。我不认为 C++ 可以修改文字,即使它让你尝试,但它仍然强制执行此约定以提醒程序员文字值不能被修改。
因为文字是常量。 1不能变成2,"abd"
不能变成"edf"
.
如果 C++ 允许您通过非 const
引用获取文字,那么它会:
- 必须允许字面量动态改变它们的含义,允许您将 1 变成 2。
- 希望程序员格外小心,仅通过那些不引用文字的引用来修改值,并在出错时调用未定义的行为。
(1) 会在你的程序中造成混乱,因为 x == 1
可能意味着 "is x equal to 2" 取决于上下文,并且 (2) 是不可能实现的,因为 void display(int& a)
应该如何想知道它是否收到文字引用?
由于这两个选项都没有意义,文字只能通过 const
引用传递。
实际上,从字符串文字到 char*
的弃用转换很好地说明了为什么规则很有意义,尽管它不是引用而是指针。您可以让 char*
指向 "abc"
,但尝试实际利用 char*
的 "modifiability" 属性并修改其中一个 char
元素导致未定义的行为。这使得整个弃用的转换既危险又无用(在非遗留代码中)。
你不会想在语言的所有其他部分遇到这样的麻烦吧?
将任何对象视为 盒子,其中包含一些值,盒子可能有也可能没有名称标签,即盒子 with 名称标签为 variable
,框 没有 名称标签为 literal
。不管有没有名牌,我们有盒子。
Reference
是我们将名称标签添加到我们的盒子的方式。
int a = 5;
int &b = a;
我们的盒子有 两个 个名称标签(里面的值为 5
)。
const int &c = 5;
给你,盒子刚刚命名。
以前从未有过名字的盒子的新名字必须标记为const
。因为盒子里面的值可以通过它的名字来改变,我们不希望它发生(不允许发生)到我们的literal
盒子。
最后一个问题:
how can a const reference keep pointing to an R-Value (anonymous variable)
Here is the answer。 C++ 语言说本地 const 引用将临时值的生命周期延长到包含范围的末尾,但可以节省复制构造的成本(即,如果您改用局部变量)。
右值是一个临时的消逝对象,可以读取但即将被销毁。也是不能留在赋值左边的值(给这种鬼东西赋值怎么理解?)
C++ 有一种非常特殊的方法来处理这种实体。如果你可以通过(非常量)引用传递一个右值,你也可以从函数内部给它赋值。因此,如果要通过引用传递 r 值,则规则必须是 const 引用。
虽然这不是全部事实,因为您确实有 r 值引用(用 &&
表示)。所以,你最终可以操作一个临时对象,但你必须明确声明你真的想这样做,使用右值引用。