【问题标题】:`auto` specifier type deduction for references引用的`auto`说明符类型推导
【发布时间】:2012-08-06 21:15:51
【问题描述】:

让我们考虑下面的代码sn-p

void Test()
  {
  int x = 0;

  int& rx = x;
  int* px = &x;

  auto apx = px;    // deduced type is int*
  auto arx = rx;    // deduced type is int
  }

可以从指针类型中进行类比,期望arx 的推导类型是int&,但实际上它是int

标准中的规则是什么?背后的原因是什么? 有时我会在这样的情况下被它抓住:

const BigClass& GetBigClass();
...
auto ref_bigclass = GetBigClass();   // unexpected copy is performed

【问题讨论】:

    标签: c++ c++11 type-inference


    【解决方案1】:

    使用auto&:

    auto& ref_bigclass = GetBigClass();
    

    引用应该是透明的:对它们的任何操作都发生在它们引用的对象上,没有办法“获取”引用本身。

    UPD:这在 7.1.6.4/6 中有所介绍:

    一旦根据 8.3 确定了 declarator-id 的类型,使用 declarator-id 声明的变量的类型就使用模板参数推导规则从其初始化程序的类型中确定。

    并且模板参数推导在14.8.2.1/3中定义:

    如果模板参数类型P为引用类型,则P引用的类型用于类型推导。

    附:请注意,这与 decltype 不同:decltype(rx) 将产生 int& 类型 (7.1.6.2/4)。

    【讨论】:

    • 这很清楚,但为什么我不必对指针做同样的事情呢?
    • @Andrey:因为指针是对象类型,所以引用不是。你可以有一个引用指针,但不能有一个指针引用或引用引用。
    • @Andrey 这就是引用的意义——通过使用它们,您引用的是底层值,而不是引用本身,而指针本身就是值。
    【解决方案2】:

    考虑它的最简单方法是将其与模板参数推导进行比较。

    给定:

    template<typename T>
    void deduce(T) { }
    

    如果你打电话:

    deduce(px);
    

    那么模板参数T将被推导出为int*,如果你调用

    deduce(rx);
    

    那么T将被推导出为int,而不是int&amp;

    当你使用auto时,你会得到相同的类型。

    可以从指针类型进行类比,期望arx 的推导类型是int&amp;

    您必须有一个相当混乱的 C++ 语言模型才能进行类比。仅仅因为它们以语法相似的方式声明,因为 Type@ 带有类型和修饰符不会使它们以相同的方式工作。指针是一个值,一个对象,它可以被复制并通过赋值来改变它的值。引用不是对象,它是对某个对象的引用。引用不能被复制(复制它会复制所指对象)或更改(分配给它会改变所指对象)。返回指针的函数返回对象按值(所讨论的对象是指针对象),但返回引用的函数(如您的GetBigClass())返回对象按参考。它们是完全不同的语义,试图在指针和引用之间进行类比是注定要失败的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-11
      • 1970-01-01
      • 2019-01-01
      • 1970-01-01
      • 2014-12-10
      • 1970-01-01
      相关资源
      最近更新 更多