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

min*_*ang 71 c++ reference auto c++11

请看下面的简单代码:

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

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

static Foo g_temp;
const Foo& GetFoo() { return g_temp; }
Run Code Online (Sandbox Code Playgroud)

我试着auto像这样使用:

auto my_foo = GetFoo();
Run Code Online (Sandbox Code Playgroud)

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

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

const auto& my_foo2 = GetFoo();
      auto& my_foo3 = GetFoo();
Run Code Online (Sandbox Code Playgroud)

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

som*_*guy 63

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


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

auto a1 = i;
auto a2 = ci;
auto a3 = *pci;
auto a4 = pcs->i;
Run Code Online (Sandbox Code Playgroud)

在模板参数和自动变量的类型推导期间,仅删除顶级对象.给定一个带有指针或引用参数的函数模板,保留指向或引用的任何内容的常量:

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

这种行为是旧闻,适用于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
Run Code Online (Sandbox Code Playgroud)

由于您可以保留cv-qualifier(如果类型是引用或指针),您可以执行以下操作:

auto& my_foo2 = GetFoo();
Run Code Online (Sandbox Code Playgroud)

而不是必须指定它const(相同volatile).

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

const Foo my_foo = GetFoo();
Run Code Online (Sandbox Code Playgroud)

以上将创建一个副本,因为它my_foo是一个值.如果auto要返回左值引用,则无法进行上述操作.

  • 你没有解释为什么ref-qualifier也被删除了. (7认同)
  • 不要告诉我; 把它放在你的答案中. (5认同)
  • @Tomalak Geret'kal:你的意思是他们为什么决定这样做?这很有道理,不是吗?考虑一下:`Foo my_foo = GetFoo();`并且`GetFoo()`没有返回const类型.它将是:`auto my_foo = GetFoo();`.如果自动包含参考,您将无法执行上述操作. (3认同)
  • 链接到文章http://aristeia.com/Papers/appearing%20and%20disappearing%20consts.pdf (2认同)