简体   繁体   English

C++11 自动和 decltype

[英]C++11 auto and decltype

when reading about auto and decltype (C++11) i see the below function在阅读有关 auto 和 decltype (C++11) 的内容时,我看到以下内容 function

auto findMin(A a, B b) -> decltype(a < b ? a : b)
{
    return (a < b) ? a : b;
}

this part -> decltype(a < b? a: b) is strange to me.这部分 -> decltype(a < b? a: b) 对我来说很奇怪。 what kind of function declaration or it just applies for auto and decltype only?什么样的 function 声明或者它只适用于 auto 和 decltype?

this part -> decltype(a < b? a: b) is strange to me.这部分 -> decltype(a < b? a: b) 对我来说很奇怪。 what kind of function declaration or it just applies for auto and decltype only?什么样的 function 声明或仅适用于 auto 和 decltype?

The arrow -> following auto and the parenthesis, denotes a trailing return type, and it allows you to specify the return type after knowing the function parameters - more freedom if you will. auto和括号后面的箭头->表示尾随返回类型,它允许您在知道 function 参数后指定返回类型 - 如果您愿意,可以更自由。

decltype gives us the declared type and this allows us to inspect the type of an expression. decltype为我们提供了声明的类型,这允许我们检查表达式的类型。

In the ternary expression a < b? a: b在三元表达式a < b? a: b a < b? a: b , the type of the expression is the common type between a and b . a < b? a: b ,表达式的类型是ab通用类型 That is, for int and double the common type is double as int promotes to double .也就是说,对于intdouble常见类型double ,因为int提升为double

Calling decltype with the mentioned expression decltype(a < b? a: b) then gives us the common type that will be the type of the return value that findMin returns.使用提到的表达式decltype(a < b? a: b)调用decltype然后给我们一个公共类型,它将是findMin返回的返回值的类型。 The function still needs to return a value and so we see the expression there as well. function 仍然需要返回一个值,所以我们在那里也看到了表达式。


Ps the common type behaviour of the ternary expression is captured by the std::common_type trait (since c++11) Ps 三元表达式的常见类型行为由std::common_type特征捕获(自 c++11 起)

decltype() is different from the auto keyword . decltype()不同于auto keyword We declare a variable in auto and we have to give it a first value.我们在auto中声明了一个变量,我们必须给它一个第一个值。 decltype() corresponds to a type. decltype()对应一个类型。 There are 2 separate sets of rules for decltype() . decltype()有两套独立的规则。

1) decltype(name) 1)decltype(名称)

Examples;例子;

decltype(x)
decltype(x.y)
decltype(ptr->a)

/*The compiler will look at what the type for this name is and think that- 
the type obtained with decltype is that type.*/

int ival;               decltype(ival) x; -----> int x;         
double dval;            decltype(dval) x; -----> double x;


 struct Data{           
    int mx;
    };

Data data;              decltype(data.mx) x; -----> int x;

Data *p=&data;          decltype(p->mx) x;   -----> int x;

Note : We can use decltype wherever we use type because decltype means type.注意:我们可以在任何使用类型的地方使用decltype ,因为 decltype 表示类型。

Note : const is ignored in auto keyword , but const is not ignored in decltype .注意constauto keyword中被忽略,但constdecltype不被忽略

const int cx=10;        decltype(cx) y=10; -----> const int y=10;

Note : reference(&) is ignored in auto keyword , but reference(&) is not ignored in decltype .注意reference(&)auto keyword中被忽略,但reference(&)decltype不被忽略

int x=10;
int &r=x;
decltype(r) foo(); ----->  int& foo();

int x=10;
const int &r=x;
decltype(r) y=x;  -----> const int& y;

Note :No array to pointer conversion ( array decay ) in decltype .注意decltype中没有数组到指针的转换(数组衰减)。

int a[] {1,2,3,4};
decltype(a) b; -----> int b[4];

2) decltype(expression) 2) decltype(表达式)

decltype (x)   -----> 1. Rule set
decltype ((x)) -----> 2. Rule set

All of the examples below will apply the 2nd rule set, so it's no longer a name but an expression .下面的所有示例都将应用第二个规则集,因此它不再是 name 而是expression

decltype (10);
decltype (x+5);
decltype (x++);
decltype ((y));
decltype (*ptr);
decltype (a[5]);

Note : In this rule set, type inference depends on whether the expression is Lvalue , Rvalue , or Xvalue .注意:在此规则集中,类型推断取决于表达式是LvalueRvalue还是Xvalue Note : If the expression is a PRValue expression , the resulting type is directly the type of that expression.注意:如果表达式是PRValue expression ,则结果类型直接是该表达式的类型。

decltype(10) x; // x is int.            
int x=20;       
decltype(x+4.5) dval;  // dval is double.

Note : If the operand of the decltype operator is not a name,if expression is in value category PRvalue expression , the type obtained with decltype is type T .If the expression is in the Lvalue expression value category, the type obtained with decltype is T& .If the expression is in the Xvalue expression value category, the type obtained with decltype is T&& .注意:如果decltype运算符的操作数不是名字,如果expression属于值范畴PRvalue expression ,则decltype获得的type T 。如果表达式属于Lvalue Lvalue expression值范畴,则decltype获得的类型为T& .如果表达式属于Xvalue expression值类,则decltype得到的类型为T&&

If the expression is an Lvalue expression, examples of its status are given below.如果表达式是左值表达式,下面给出了它的状态示例。

int x=20;
decltype(++x) y=x;  -----> int & y;

int x=20;
int *ptr=&x;
decltype(*ptr) y=x; -----> int & y;

int a[10] [20] {};
decltype (a[2][5])  ----->int &;

int x=10;                                                       
decltype(x)   -----> int
decltype((x)) -----> Since the variable x is an Lvalue, the type of the expression is int&.

Note: The compiler does not generate an opcode for the expression that is the operand of the decltype operator注意:编译器不会为作为 decltype 运算符的操作数的表达式生成操作码

    int x=20;
    decltype(x++) y=45; -----> y is int.
    decltype(++x) y=x; -----> Since ++x is an Lvalue y is int&. x=20 because the compiler does not generate an opcode for the expression that is the operand of the decltype operator

C++11 allows two ways to declare a function's return type C++11 允许两种方式声明函数的返回类型

  1. return_type function_name(arg1_type arg1, arg2_type arg2); return_type function_name(arg1_type arg1, arg2_type arg2);

    Ex.前任。 int bar(int x, int y);整数条(整数 x,整数 y);

  2. auto function_name(arg1_type arg1, arg2_type arg2) -> return_type;自动函数名(arg1_type arg1,arg2_type arg2)-> return_type;

    Ex.前任。 auto foo(int x, int y) -> int自动 foo(int x, int y) -> int

The first way is called ' prefix return type '.第一种方式称为'前缀返回类型'。 The second one, obviously is called ' suffix return type '.第二个,显然叫做'后缀返回类型'。 The 'suffix return type' is not just another fancy way to specify return types. “后缀返回类型”不仅仅是另一种指定返回类型的奇特方式。 It plays very important when doing generic programming.它在进行泛型编程时非常重要。

Let me explain how.让我解释一下。

'auto' type specifier is a great feature provided by C++11 which lets you define variables whose type can be deduced by the compiler. 'auto' 类型说明符是 C++11 提供的一项很棒的功能,它允许您定义可以由编译器推断其类型的变量。 But there is a catch.但是有一个问题! The programmer needs to help the compiler deduce the type of an 'auto' variable using an initializer.程序员需要帮助编译器使用初始化器推断“自动”变量的类型。 For example, in case of例如,如果

auto x = 100;

the compiler deduces type of x to be 'int' or in case of编译器将 x 的类型推断为“int”或在以下情况下

auto y{'t'};

the compiler deduces type of y to be 'list of char'编译器将 y 的类型推断为“字符列表”

Compiler's job of deducing the type is simpler when the initializer's type is simple and already known like above.当初始化器的类型很简单并且如上所述已知时,编译器推断类型的工作会更简单。 But it is not always that simple.但这并不总是那么简单。 Sometimes, the data type of auto variable or return value is dependent on the type / computation of other variables.有时,自动变量或返回值的数据类型取决于其他变量的类型/计算。 For example, in case of a template function, the return type needs to be determined based on the data type of input variables and/or the computation.例如,在模板 function 的情况下,需要根据输入变量的数据类型和/或计算来确定返回类型。

That is when decltype() specifier comes into the picture.这就是 decltype() 说明符出现的时候。

decltype(expr)

As it's name suggests, declaration type specifier, deduces type of an expression fed to it.顾名思义,声明类型说明符推断提供给它的表达式的类型。

A rule of thumb I forgot to mention before, a compiler parses an expression left to right.我之前忘记提到的一条经验法则是,编译器从左到右解析表达式。

template<typename X, typename Y>
auto mul(X a, Y b) -> decltype(a*b)

Here, the compiler sees auto as a placeholder for the type that 'decltype' takes responsibility of deducing based on the expression it is fed.在这里,编译器将 auto 视为类型的占位符,“decltype”负责根据输入的表达式进行推导。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM