自动演绎类型? [英] How does auto deduce type?

查看:99
本文介绍了自动演绎类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在某些情况下使用 auto

auto s = expr;          //s is always lvalue
auto & s = expr;        //s is always lvalue reference? What if expr is rvalue?
auto && s = expr;       //s is perfectly forwarded

它们是真的吗?如果不是,为什么?

Are they true? If not, why?

推荐答案

dyp是正确的,我想详细说明。

dyp is correct and I would like to elaborate.

首先,结论是来自dyp:

First of all, the conclusion is the from dyp:


auto <推断的类型/ code>通过模板参数推导的规则在
中定义变量的声明,请参见[dcl.spec.auto] / 6;
有一个例外:如果初始化程序是一个括号初始列表,则
推导的类型是 std :: initializer_list

我会解释。

首先,

auto s = expr;

这与从中推导 T 相同 expr

template<class T>
void f(T s);

f(expr);

模板参数推导的规则非常复杂,因为您只关心左值和右值的东西,让我们集中讨论这个问题。

The rule for template argument deduction is quite complicated, since you are only concerning with the lvalue and rvalue stuff, let's focus on this.

模板参数推导是通过比较模板参数类型(在 P 中称为这种情况下 P T ),以及相应的自变量(称为 A ,在这种情况下为 expr )的类型。

Template argument deduction is by comparing the template parameter type (call it P, in this case P is T), and the corresponding argument (call it A, in this case, the type of expr).

从14.8.2.1开始,

From 14.8.2.1,


如果P不是引用类型:

If P is not a reference type:

-如果A是数组类型,由数组到指针标准转换(4.2)产生的指针类型为
,代替A进行类型推导;否则,

— If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction; otherwise,

-如果A是函数类型,则使用函数到指针标准转换(4.3)
产生的指针类型代替A用于类型推导;否则,

— If A is a function type, the pointer type produced by the function-to-pointer standard conversion (4.3) is used in place of A for type deduction; otherwise,

-如果A是具有简历资格的类型,则将A的顶级顶级简历限定词用于类型推导。

— If A is a cv-qualified type, the top level cv-qualifiers of A’s type are ignored for type deduction.

因此,如果 expr 是数组或函数,则如果expr具有cv限定符,它将被视为指针( const 等),它们将被忽略。

So, if expr is array or function, it will be treated as pointers, if expr has cv-qualification (const etc), they will be ignored.


如果 P 是cv限定类型,则顶级cv限定符 P 类型的类型将被忽略以进行类型推导。

If P is a cv-qualified type, the top level cv-qualifiers of P’s type are ignored for type deduction.

这实际上是说:

const auto s = expr;

s const 变量,但出于 auto 目的的类型推断,将删除 const

s is a const variable, but for type deduction for auto purposes, the const will be removed.

因此,根据上述规则, auto 将被推导为的类型。 expr (经过上述类型的转换后)。

Thus, from the above rules, auto will be deduced to the type of expr (after some type conversion stated above).

请注意,当表达式是对 T ,它将在进行先前分析之前调整为 T

Note that, when an expression is a reference to T, it will be adjusted to T before prior analysis.

$ c> expr 是– rvalue,lvalue或lvalue / rvalue引用类型– auto 的类型将始终是<$ c的类型$ c> expr ,无需引用。

So whatever expr is – rvalue, lvalue, or lvalue/rvalue ref type – the type of auto will always be the type of expr without reference.

auto s1 = 1; //int
int &x = s1;
auto s2 = x; //int
int &&y = 2;
auto s3 = y; //int

第二,我们来看一下

auto &s = expr;

这将与

template<class T>
void f(T &s);

f(expr);

标准的额外规则如下:


如果 P 是引用类型,则 P 引用的类型是

If P is a reference type, the type referred to by P is used for type deduction.

因此对auto的扣除与没有& ,但是在扣除 auto 类型之后,将& 添加到<$的末尾c $ c> auto 。

So the deduction of auto will be exactly same as without &, but after the auto type is deducted, the & is added to the end of auto.

//auto &s1 = 1; //auto is deducted to int, int &s1 = 1, error!
const auto &s1 = 1; //auto is deducted to int, const int &s1 = 1; ok!
const int &x = s1;
auto &s2 = x; //auto is int, int &s2 = x; ok!
int &&y = 2;
auto &s3 = y; //auto is int, int &s3 = y; ok! 

请注意,最后一个 y 是左值。 C ++的规则是:命名的右值引用是左值。

Note that the last y is an lvalue. The rule of C++ is: named rvalue reference is an lvalue.

最后:

auto &&s = expr;

毫无疑问,这与

template<class T>
void f(T &&s);

f(expr);

标准中的另一条规则:


如果 P 是对cv不合格模板参数的右值引用,而
参数是左值,则类型为 A用于 A
位置以进行类型推导。

If P is an rvalue reference to a cv-unqualified template parameter and the argument is an lvalue, the type "lvalue reference to A" is used in place of A for type deduction.

这实际上表示,如果 expr 是一个右值,则规则将与第二种情况(左值情况)相同,但是如果 expr 是左值, A 的类型将是对 A 的左值引用。

This actually says that, if expr is an rvalue, the rule will be same as the second case (lvalue case), but if expr is an lvalue, the type of A will be an lvalue reference to A.

前面的说明中解释过, A 绝不是引用,因为表达式的类型绝不是引用。但是对于这种特殊情况( auto& ,而 A 是左值),引用<$ c不管 expr 本身是否是引用类型,都必须使用$ c> A 。

Note from previous explained, A is never reference, because the type of an expression is never a reference. But for this special case (auto &&, and A is an lvalue), reference to A must be used, regardless expr itself is a reference type or not.

示例:

auto &&s1 = 1; //auto is deducted to int, int &&s1 = 1, ok!
int x = 1;
auto &&s2 = x; //x is lvalue, so A is int &, auto is deducted to int &, int & &&s2 = x; ok!
int &&y = 2;
auto &&s3 = y; //y is lvalue, auto is int &, int & &&s3 = y; ok!

这篇关于自动演绎类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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