C++11 auto:如果它得到一个常量引用怎么办? [英] C++11 auto: what if it gets a constant reference?

查看:24
本文介绍了C++11 auto:如果它得到一个常量引用怎么办?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面的简单代码:

class Foo{民众:Foo(){}~Foo(){}Foo(const Foo&){}Foo&运算符=(const Foo&) { 返回 *this;}};静态 Foo g_temp;const Foo&GetFoo() { 返回 g_temp;}

我尝试像这样使用 auto:

auto my_foo = GetFoo();

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

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

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

问题:为什么 autoGetFoo 的返回类型推导出为对象,而不是引用?

解决方案

阅读这篇文章:C++ 中常量的出现和消失

<小时><块引用>

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

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

<块引用>

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

templatevoid f(T& p);国际我;const int ci = 0;const int *pci = &i;f(i);//和之前一样,调用 f,即 T 是 intf(ci);//现在调用 f,即 T 是 const intf(*pci);//也调用 f,即 T 是 const int

<块引用>

这种行为是旧闻,适用于 C++98 和C++03.自动变量的相应行为当然是C++0x 新手:

auto&a1 = i;//a1 是 int& 类型自动&a2 = ci;//a2 的类型是 const int&自动&a3 = * pci;//a3 也是 const int& 类型自动&a4 = pcs->i;//a4 也是 const int& 类型

<小时>

因为如果类型是引用或指针,你可以保留 cv 限定符,你可以这样做:

auto&my_foo2 = GetFoo();

不必将其指定为 const(volatile 也是如此).

至于为什么 autoGetFoo() 的返回类型推导出为值而不是引用(这是您的主要问题,抱歉),考虑一下:

const Foo my_foo = GetFoo();

以上将创建一个副本,因为 my_foo 是一个值.如果 auto 返回一个左值引用,则上述情况是不可能的.

Please take a look at the following simple code:

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

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

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

I tried to use auto like this:

auto my_foo = GetFoo();

I expected that my_foo will be a constant reference to Foo, which is the return type of the function. However, the type of auto is Foo, not the reference. Furthermore, my_foo is created by copying g_temp. This behavior isn't that obvious to me.

In order to get the reference to Foo, I needed to write like this:

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

Question: Why does auto deduce the return type of GetFoo as an object, not a reference?

解决方案

Read this article: Appearing and Disappearing consts in C++


Type deduction for auto variables in C++0x is essentially the same as for template parameters. (As far as I know, the only difference between the two is that the type of auto variables may be deduced from initializer lists, while the types of template parameters may not be.) Each of the following declarations therefore declare variables of type int (never const int):

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

During type deduction for template parameters and auto variables, only top-level consts are removed. Given a function template taking a pointer or reference parameter, the constness of whatever is pointed or referred to is retained:

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

This behavior is old news, applying as it does to both C++98 and C++03. The corresponding behavior for auto variables is, of course, new to 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


Since you can retain the cv-qualifier if the type is a reference or pointer, you can do:

auto& my_foo2 = GetFoo();

Instead of having to specify it as const (same goes for volatile).

Edit: As for why auto deduces the return type of GetFoo() as a value instead of a reference (which was your main question, sorry), consider this:

const Foo my_foo = GetFoo();

The above will create a copy, since my_foo is a value. If auto were to return an lvalue reference, the above wouldn't be possible.

这篇关于C++11 auto:如果它得到一个常量引用怎么办?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆