C ++ 11 auto:如果得到一个常量引用怎么办?


77

请看下面的简单代码:

class Foo
{
public:
  Foo(){}
  ~Foo(){}

  Foo(const Foo&){}
  Foo& operator=(const Foo&) { return *this; }
};

static Foo g_temp;
const Foo& GetFoo() { return g_temp; }

我试图这样使用auto

auto my_foo = GetFoo();

我希望这my_foo将是对的常量引用Foo,这是函数的返回类型。但是,类型autoFoo,而不是引用。此外,my_foo通过复制创建g_temp。这种行为对我而言并不那么明显。

为了获得对的引用Foo,我需要这样编写:

const auto& my_foo2 = GetFoo();
      auto& my_foo3 = GetFoo();

问题:为什么auto推断出GetFoo作为对象而不是引用的返回类型?


VC ++ 2010和Intel C ++编译器
minjang 2011年

Answers:


64

阅读本文:C ++中的const出现和消失


C ++ 0x中自动变量的类型推导与模板参数基本相同。(据我所知,两者之间的唯一区别是,可以从初始化列表中推导出自动变量的类型,而不能从模板参数列表中推导出。)因此,以下每个声明都声明了int类型的变量(从不const int):

auto a1 = i;
auto a2 = ci;
auto a3 = *pci;
auto a4 = pcs->i;

在模板参数和自动变量的类型推导过程中,仅删除顶级const。给定一个带有指针或引用参数的函数模板,将保留所指向或引用的对象的常数:

template<typename T>
void f(T& p);

int i;
const int ci = 0;
const int *pci = &i;

f(i);               // as before, calls f<int>, i.e., T is int
f(ci);              // now calls f<const int>, i.e., T is const int
f(*pci);            // also calls f<const int>, i.e., T is const int

此行为是旧消息,适用于C ++ 98和C ++ 03。自动变量的相应行为当然是C ++ 0x的新特性:

auto& a1 = i;       // a1 is of type int&
auto& a2 = ci;      // a2 is of type const int&
auto& a3 = *pci;    // a3 is also of type const int&
auto& a4 = pcs->i;  // a4 is of type const int&, too

如果类型是引用或指针,则可以保留cv限定词,因此可以执行以下操作:

auto& my_foo2 = GetFoo();

不必将其指定为const(相同volatile)。

编辑:至于为什么auto推断GetFoo()作为值而不是引用的返回类型(这是您的主要问题,很抱歉),请考虑以下问题:

const Foo my_foo = GetFoo();

上面将创建一个副本,因为它my_foo是一个值。如果auto要返回左值引用,则上述操作是不可能的。


10
您没有解释为什么也删除了ref限定符。
Lightness Races in Orbit

3
@Tomalak Geret'kal:你的意思是为什么他们决定这样做?这是有道理的,不是吗?试想一下:Foo my_foo = GetFoo();GetFoo()没有返回一个const类型。它将与:相同auto my_foo = GetFoo();。如果auto也包含参考,则您将无法执行上述操作。
someguy 2011年

7
不要告诉我 把它放在你的答案。
Lightness Races in Orbit


1
《有效的现代C ++》一书中的Scott Meyers专门用一整章来解释这一点。必须阅读。
dehinrsu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.