c++ - const 引用的类型是什么?

标签 c++ templates types typedef const-reference

我知道将 const 引用变量传递给函数的 const 引用参数不会导致函数参数的类型为“const reference of a const reference of the referee's type”。 const 引用参数的变量名仅被视为 refere 的另一个别名,但受到保护,即该别名不能用于修改 refere。

将引用变量的名称用作引用变量的别名的想法很好地适用于变量,提供了另一层间接性。应用类似的想法似乎没有意义:

  • const 引用类型本身被用作其引用者类型的别名,
  • const 引用类型typedef 用作其引用者类型 的别名,
  • 当模板参数为 typename T 时,传递给(或由其推导出)template 参数的 const 引用变量将其类型解释为其 refere 的类型及其函数参数是 T const&

但这似乎发生在以下情况中:

#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"
}
  1. 为什么即使对于已经是 int const& 的参数,函数模板也能正常工作? (在示例代码中,它甚至适用于将 int const& 变量作为第一个参数并将 int 变量作为第二个参数的调用。)它不应该是无效,因为 C++ 不 允许“reference of a reference”

  2. int const&typeidname() 不应该是 int const& , 而不是 int?

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

  4. 回到变量名,给定:

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

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

最佳答案

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

C++ 中的表达式从不解释为具有引用类型。每个物理上具有引用类型的表达式总是被解释为非引用类型的左值(或xvalue)。 “引用”部分立即不可逆转地丢弃和遗忘。

标准中是这样写的(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 限定)。

返回到您的代码,在此调用中

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

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

typeid 的工作原理与您观察到的完全相同。 typeid 不会为您提供对象的声明类型。 typeid 的参数在您的案例中是一个表达式。这种形式的 typeid 为您提供了表达式结果的类型,这就是 typeid 无法“看到”引用的原因。 const 部分被丢弃,因为这正是 typeid 的工作方式:顶级 cv-qulifiers 总是被 typeid 丢弃。

关于c++ - const 引用的类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20556587/

相关文章:

c++ - 使用 CRTP 时 clang++ 不接受使用模板模板参数

node.js - AngularJS - 服务器端渲染

go - 如何编写一个采用 go 中多种类型之一的函数?

C++ : storing a 13 digit number always fails

c - 在 C 中打印类型转换类型

c++ - 如何使用 boost::bind 绑定(bind)类成员函数?

c++ - 使用条件语句迭代 multimap

c++ - 在模板类中实例化嵌套模板函数

c++ - 从一组字符串派生 RegExp

c++ - 在 std::unordered_map 中 move 插入/放置失败后恢复 move 的元素