引用的`auto`说明符类型推导

And*_*rey 8 c++ type-inference c++11

让我们考虑以下代码片段

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
  }
Run Code Online (Sandbox Code Playgroud)

人们可以从指针类型中得出类比,期望推导出的类型arxint&,但int事实上.

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

const BigClass& GetBigClass();
...
auto ref_bigclass = GetBigClass();   // unexpected copy is performed
Run Code Online (Sandbox Code Playgroud)

ham*_*ene 12

用途auto&:

auto& ref_bigclass = GetBigClass();
Run Code Online (Sandbox Code Playgroud)

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

UPD:7.1.6.4/6中对此进行了介绍:

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

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

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

PS注意这是不同的decltype:decltype(rx)将产生int&类型(7.1.6.2/4).

  • @Andrey:因为指针是对象类型,所以引用不是.您可以使用引用指针,但不能指向引用指针或引用引用. (4认同)
  • 这很清楚,但为什么我不必为指针做同样的事情呢? (2认同)
  • @Andrey 这就是引用的含义——通过使用它们,您可以引用底层值,而不是引用本身,而指针本身就是值。 (2认同)

Jon*_*ely 8

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

鉴于:

template<typename T>
void deduce(T) { }
Run Code Online (Sandbox Code Playgroud)

如果你打电话:

deduce(px);
Run Code Online (Sandbox Code Playgroud)

然后模板参数T将被推断为int*,如果你打电话

deduce(rx);
Run Code Online (Sandbox Code Playgroud)

然后T将推断为int,而不是int&

您使用时会得到相同的类型auto.

可以从指针类型中得出一个类比,期望推导出的类型arxint&

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