关于c ++:const引用的类型是什么?

What is the type of a const reference?

我知道将const引用变量传递给函数的const引用参数不会导致该函数参数的类型为"裁判类型的const引用的const引用"。 const reference参数的变量名仅被视为裁判的另一个别名,但因保护该别名不能用于修改裁判而受到赞扬。

使用引用变量名称的想法就像是引用变量的别名一样,很好地适用于变量,从而提供了另一层间接性。应用类似的想法似乎没有意义:

  • const引用类型本身被使用,就好像是其引用者类型的别名一样,
  • 常量引用类型的typedef用作其引用者类型的别名,
  • 当模板参数为typename T并且其功能参数为T const&时,传递给template参数(或由其推断)的const参考变量的类型将解释为其引用方的类型。

但这就是以下情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <typeinfo>
#include <iostream>

template <typename T>
T const& min(T const& a, T const& b) {
    std::cout << typeid(a).name() << std::endl;
    std::cout << typeid(b).name() << std::endl;
    return a < b ? a : b;
}

int main() {
    int x = 6, y = 7;
    int const& rx = x;
    std::cout << typeid(rx).name() << std::endl;           //"int"
    int z = ::min(rx, y);       //output shows both"a" and"b" are of type"int"
    std::cout << z << std::endl;                           //"6"
    typedef int const& icr;
    std::cout << typeid(icr).name() << std::endl;          //"int"
    std::cout << typeid(int const&).name() << std::endl;   //"int"
}
  • 为什么函数模板甚至对于已经为int const&的参数都有效? (在示例代码中,即使将int const&变量作为第一个参数并将int变量作为第二个参数的调用也可以使用。)它是否无效,因为C ++不会
    允许"参考的参考"?

  • int const&typeidname()是否应该是int const&,而不是int

  • 如果不是,那么这是否意味着int const&int的别名;这没有任何意义,因为两者都是不同的类型(不是变量的名称)?

  • 回到变量名,给定:

    1
    2
    3
    int num = 8;
    int const& ref = num;
    std::cout << typeid(ref).name() << std::endl;

    为什么输出int,而不是int const&


  • 因为引用在类型推导的上下文中折叠,所以const也是如此。查找参考崩溃,已经有很多答案。

  • 不,因为引用是透明的,所以您无法查看它们。当您命名引用变量时,该语言始终认为您是指裁判。当您引用的typeidconst时,它将忽略它。

  • 避免将诸如变量之类的不重要词加粗,这会使您的问题难以理解:)


  • 函数参数是表达式,而不是对象。即使您提供一个对象作为函数参数,它仍然是一个表达式。模板参数推导过程不适用于该对象的声明类型。它不在乎其确切的声明类型。它关心的是该表达式的类型。

    C ++中的表达式从不解释为具有引用类型。物理上具有引用类型的每个表达式始终被解释为非引用类型的左值(或x值)。"参考"部分将立即且不可逆地丢弃和遗忘。

    这就是标准(5/5)中的措辞

    5 If an expression initially has the type"reference to T" (8.3.2,
    8.5.3), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference,
    and the expression is an lvalue or an xvalue, depending on the
    expression.

    例如,在您的代码中rx被声明为int const &。但是,每次将rx用作表达式时,该表达式的结果总是立即从int const &调整为int const,并被视为int const类型的左值。在"表达式结果"上下文中,该语言完全忽略了rx是引用的事实。

    人们常说引用可以被认为是现有对象的另一个名称。这正是在这里起作用的原理。在"表达式结果"上下文中,rxx之间没有区别(除了const限定)。

    在此调用中返回您的代码

    1
    int z = ::min(rx, y);

    函数参数分别解释为int constint类型的左值。 (即,第一个参数并没有真正被视为具有int const &类型,这与您的预期相反)。这些是用于模板自变量推导的类型。因此,将T推导出为int。在此过程中的任何时候都不会尝试产生"参考引用"。

    typeid的工作原理与您完全相同。 typeid不会为您提供对象的声明类型。在您的情况下,typeid的参数是一个表达式。这种形式的typeid为您提供表达式结果的类型,这就是typeid无法"看到"引用的原因。丢弃const部分是因为typeid的工作方式:顶级cv-qulifiers始终被typeid丢弃。