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
  }

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

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

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

2 回答 2

14

使用auto&

auto& ref_bigclass = GetBigClass();

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

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)不同。

于 2012-08-09T15:44:02.580 回答
11

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

鉴于:

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

如果你打电话:

deduce(px);

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

deduce(rx);

那么T将被推断为int,而不是int&

使用auto.

可以从指针类型中进行类比,期望推导的类型arxint&

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

于 2012-08-09T16:09:23.977 回答