首页 > 其他分享 >decltype demystified

decltype demystified

时间:2024-12-23 19:08:37浏览次数:3  
标签:decltype xvalue demystified lvalue prvalue expression define

读了这个文章,决定做个总结

  1. decltype is given two entirely different purposes that are related enough to be confusing and lead to bad typos
  2. Every expression in C++ has both a type and a value category

这里面值类别(value category)是一个在C++标准中也比较混乱的概念(a tangled mess),每个表达式的值类别为这三种之一:lvalue, prvalue, xvalue 不同的built-in操作符会对操作数有要求,并返回不同的值类别。

作者总结了一个概念"expression decltype",几乎每个表达式都有这个属性,且这个概念可以明确地表明表达式的值类别,并且可以通过调整从而仅包含值类别。

First, in some cases (such as casts), the expression decltype is explicit and maybe even textually part of the expression. 
Second, the expression decltypes of built-in operators are analogous to the return types of overloaded operators. Thus, programmers accustomed to operator overloading should find them intuitive (except maybe for the conditional ternary operator E1 ? E2 : E3). 
Finally, while lvalue, prvalue, and xvalue are kind of abstract concepts, you can use the compiler to check the decltype of an expression

前面提到decltype这个关键词进行两种完全不同的类型计算,这里解释一下,对于decltype(E)

  1. 如果E是一个没有被括号括起来的id-expression(e.g., x, s.field, S::field,注意非静态成员函数不能用decltype形如(s.method_ptr)),那么decltype(E)返回这些变量、成员变量、非类型模板参数被声明的类型,包括lvalue或者rvalue reference。记这种类型为variable decltype。
  2. 如果E是别的东西,包括带括号的id-expression(e.g., (x), (s.field)),那么E中任何引用都会被视作透明且不可被检测到,于是decltype(E)取得E潜在的非引用类型T,并且按照后面的规则决定是否返回一个引用:Eprvalue则返回TElvalue则返回T&Exvalue则返回T&&。记这种类型为expression decltype

safer use of decltype

可以看到,decltype的使用相当不直观,想要正确地使用它,可以在涉及decltype的地方用一种特定的约束风格去写程序。比如,相比于if (x = y),我们应该写if ((x = y))来表明自己的意图,此外,当你明确需要一个expression decltype时,你可以定义一个宏来帮助自己:

#define exprtype(E) decltype((E))

当你明确不需要expression decltype时,根据你真实的需求,采取不同的做法:

  1. neither variable nor expression decltype
    此时,你可能需要一个变量的非引用类型,不管他本身是什么类型。(auto的变量或者return type的类型推导就是这样做的)你应该考虑std::decay_t来移除引用,即:
#define autotype(v) std::decay_t<decltype(v)>
  1. really want variable decltype
    此时,你可以定义一个宏如下:
    这个宏能在输入带括号的变量时触发编译错误,但是它解决不了 vdecltype(++v) 这种情况(依然会返回引用)
#define IGNORE(x) // causes error if invoked with 2 arguments
#define APPLY_IGNORE(x) IGNORE(x)
#define PARENTHESIZED_TO_COMMA(x) ,
#define vdecltype(v) APPLY_IGNORE(PARENTHESIZED_TO_COMMA v) decltype(v)

it's better to think of value categories as synonymous with reference qualifiers on expression decltypes

接下来作者详细介绍了几种值类型的含义。

  1. prvalue
    纯右值,这个是最好理解的。通常用来构造变量,在例子auto s = std::string("hello world");中,prvalue表达式的求值过程本身不会创建对象或调用构造函数,s会直接由构造函数std::string(const char*) 构造。

  2. glvalue
    这是程序中的一个实际对象,它有地址。你可以直接给一个glvalue赋值,unless it is a function or a user-defined class with a deleted or inaccessible operator=.

  3. xvalue("expiring glvalue")
    资源即将被移动的对象的值类型。比如,在表达式求值结束就被摧毁的对象(如函数返回值被用来移动构造时)。
    std::move transforms its argument into an xvalue

  4. lvalue
    A glvalue that is not an xvalue. The archetypal lvalue expression is a variable, but things that behave like variables are lvalues, too, such as class data members and function calls returning lvalue references.

  5. rvalue

An rvalue is a prvalue or xvalue.

Why value categories matter

看到这里,后续再来。

标签:decltype,xvalue,demystified,lvalue,prvalue,expression,define
From: https://www.cnblogs.com/flametornado/p/18624054

相关文章

  • auto与decltype
    auto:1.定义:在C++中, auto 是一个类型说明符,它让编译器在编译阶段自动推导变量的类型,其类型取决于初始化表达式的类型。auto 在声明变量时使用,编译器会根据变量初始化表达式自动推断类型。#include<iostream>#include<typeinfo>usingnamespacestd;intfun(){ retu......
  • 《Head First Software Architecture》读书笔记 —— Chapter 1: software architectu
    软件架构(SoftwareArchitecture)是一个软件系统成功的基石,它不仅决定了系统的结构,也直接影响到其可扩展性、可维护性和性能表现。在这篇博客中,我们将探讨软件架构的关键维度(dimensions)、架构决策(architecturaldecisions)以及常见的架构风格(architecturalstyles),以帮助您更好......
  • 第4章 decltype说明符(C++11~C++17)
    第4章decltype说明符(C++11~C++17)4.1回顾typeof和typeid(1)在C++11标准发布以前,GCC的扩展提供了一个名为typeof的运算符。通过该运算符可以获取操作数的具体类型。typeof是GCC所提供,并非C++标准。inta=9;typeof(a)b=5;(2)C++标准还提供了一个typeid运算符来获取与目标操......
  • C++ 11 auto(自动类型推导) 和 decltype(获取表达式类型)
    C++(2)auto占位符自动类型推导auto能够实现类型的自我推导,并不代表一个实际的类型声明。auto只是一个类型声明的占位符。auto声明的变量,必须马上初始化,以让编译器推断出它的实际类型,并在编译时将auto占位符替换为真正的类型。注意:C++11中auto不能用于函......
  • 【C++】decltype
    1、简介我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行。RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通过name成员函数返回类型的名称。同时在C++11中typeid还提供了hash_code这个成员函数,用于返回类型......
  • 深入解析decltype和decltype(auto)
    decltype关键字是C++11新标准引入的关键字,它和关键字auto的功能类似,也可以自动推导出给定表达式的类型,但它和auto的语法有些不同,auto推导的表达式放在“=”的右边,并作为auto所定义的变量的初始值,而decltype是和表达式结合在一起,语法如下:decltype(expr)var;它的语法像是函数调......
  • C++11中auto与decltype的区别与联系深入解析
    文章目录一、引言二、auto关键字及其特性1、auto的基本定义与用途2、auto在类型推导中的应用3、auto的局限性及需要注意的问题三、decltype关键字及其特性1、decltype的基本定义与用途2、decltype在类型推导中的应用3、decltype的局限性及需要注意的问题四、auto与decl......
  • 06 | auto/decltype:为什么要有自动类型推导?
    我们从宏观的层面上重新认识了C++,从今天开始,我们将进入一个新的“语言特性”单元,“下沉”到微观的层面去观察C++,一起去见一些老朋友、新面孔,比如const、exception、lambda。这次要说的,就是C++11里引入的一个很重要的语言特性:自动类型推导。自动类型推导如果你有过一些......
  • C++填坑系列——类型推导 decltype
    decltypedecltype主要是为了解决类型推导的问题,特别是在模板编程和泛型编程中应用较广泛。decltype关键字用于以表达式为参数,推导表达式返回的类型,该类型会保留所有信息。c++11提出的新特性,decltype关键字。和auto一样都是用来做编译时类型推导的,但是也有一些区别:auto:从......
  • auto 和 decltype
    auto和decltype都是C++11中引入的关键字,用于自动类型推导,但它们的工作方式有所不同。auto关键字可以让编译器自动推断变量的类型,使代码更加简洁、易读4。例如:autoa=42;//a的类型被推断为intautos="hello";//s的类型被推断为constchar*但是,auto有时候会改变表......