首页 > 编程语言 >【C++】decltype

【C++】decltype

时间:2024-08-09 23:06:14浏览次数:16  
标签:decltype 推导 int auto C++ 类型 表达式

1、简介

我们之前使用的typeid运算符来查询一个变量的类型,这种类型查询在运行时进行。RTTI机制为每一个类型产生一个type_info类型的数据,而typeid查询返回的变量相应type_info数据,通过name成员函数返回类型的名称。同时在C++11中typeid还提供了hash_code这个成员函数,用于返回类型的唯一哈希值。RTTI会导致运行时效率降低,且在泛型编程中,我们更需要的是编译时就要确定类型,RTTI并无法满足这样的要求。编译时类型推导的出现正是为了泛型编程,在非泛型编程中,我们的类型都是确定的,根本不需要再进行推导。

而编译时类型推导,除了我们说过的auto关键字,还有本文的decltype。

decltype与auto关键字一样,用于进行编译时类型推导,不过它与auto还是有一些区别的。decltype的类型推导并不是像auto一样是从变量声明的初始化表达式获得变量的类型,而是总是以一个普通表达式作为参数,返回该表达式的类型,而且decltype并不会对表达式进行求值。

2、decltype用法

2.1 推导出表达式类型

    int i = 4;
    decltype(i) a; //推导结果为int。a的类型为int。

2.2 与using/typedef合用,用于定义类型

    using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
    using ptrdiff_t = decltype((int*)0 - (int*)0);
    using nullptr_t = decltype(nullptr);

    vector<int >vec;
    typedef decltype(vec.begin()) vectype;
    for (vectype i = vec.begin; i != vec.end(); i++)
    {
        //...
    }

2.3 重用匿名类型

在C++中,我们有时候会遇上一些匿名类型,如:

struct 
{
    int d ;
    doubel b;
}anon_s;

而借助decltype,我们可以重新使用这个匿名的结构体:

decltype(anon_s) as ;//定义了一个上面匿名的结构体

2.4 泛型编程中结合auto,用于追踪函数的返回值类型

这也是decltype最大的用途了。

template <typename _Tx, typename _Ty>
auto multiply(_Tx x, _Ty y)->decltype(_Tx*_Ty)
{
    return x*y;
}

3、decltype推导规则

  • 如果e是一个没有带括号的标记符表达式或者类成员访问表达式,那么的decltype(e)就是e所命名的实体的类型。此外,如果e是一个被重载的函数,则会导致编译错误。
  • 否则 ,假设e的类型是T,如果e是一个将亡值,那么decltype(e)为T&&
  • 否则,假设e的类型是T,如果e是一个左值,那么decltype(e)为T&。
  • 否则,假设e的类型是T,则decltype(e)为T。

标记符指的是除去关键字、字面量等编译器需要使用的标记之外的程序员自己定义的标记,而单个标记符对应的表达式即为标记符表达式。例如:

int arr[4]

则arr为一个标记符表达式,而arr[3]+0不是。

    int i=10;
    decltype(i) a; //a推导为int
    decltype((i))b=i;//b推导为int&,必须为其初始化,否则编译错误

这里需要提示的是,字符串字面值常量是个左值,且是const左值,而非字符串字面值常量则是个右值。

标签:decltype,推导,int,auto,C++,类型,表达式
From: https://www.cnblogs.com/servlet-context/p/18351659

相关文章

  • C++入门基础知识(笔记):成员变量和成员函数分开存储,非静态成员变量,是属于类的对象上,空对
    在C++中,类内的成员变量和成员函数分开存储只有非静态成员变量才属于类的对象上。1.空对象占用内存空间为:1个字节,代码演示:#include<iostream>usingnamespacestd;//成员变量和成员函数分开存储classPerson{};//这是一个空对象voidtest01(){ Personp;......
  • 2024年华为OD机试真题-求幸存数之和-(C++/Java/python)-OD统一考试(C卷D卷)
    2024华为OD机试真题目录-(B卷C卷D卷)-【C++JavaPython】_华为od机试csdn-CSDN博客 题目描述给一个正整数数列nums,一个跳数jump,及幸存数量left。运算过程为:从索引0的位置开始向后跳,中间跳过J个数字,命中索引为J+1的数字,该数被敲出,并从该点起跳,以此类推,直到幸存le......
  • C++入门:C语言到C++的过渡
    前言:C++——为弥补C缺陷而生的语言        C++起源于1979年,当时BjarneStroustrup在贝尔实验室工作,面对复杂软件开发任务,他感到C语言在表达能力、可维护性和可扩展性方面存在不足。        1983年,BjarneStroustrup在C语言基础上添加面向对象编程......
  • 第18 章探讨 C++新标准 移动语义和右值引用
    第18章探讨C++新标准移动语义和右值引用第18章探讨C++新标准移动语义和右值引用文章目录第18章探讨C++新标准移动语义和右值引用18.2移动语义和右值引用程序清单18.2useless.cpp18.2移动语义和右值引用现在介绍本书前面未讨论的主题。C++11支持移动语......
  • 【C++进阶学习】第十二弹——C++ 异常处理:深入解析与实践应用
    前言:在C++编程语言中,异常处理是一种重要的机制,它允许程序员在运行时捕获和处理错误或异常情况。本文将详细介绍C++异常处理的相关知识点,包括异常的定义、抛出与捕获、异常处理的原则、以及在实际编程中的应用。目录1.异常处理的基本概念1.1异常的定义1.2异常的抛出......
  • c++入门这一篇就够了!!!
    c++简介“c++”中的++来自于c语言中的递增运算符++,该运算符将变量加1。c++起初也叫”cwithclsss”.通过名称表明,c++是对C的扩展,因此c++是c语言的超集,这意味着任何有效的c程序都是有效的c++程序。c++程序可以使用已有的c程序库。     为什么c++不叫++c呢?因为它虽然对......
  • 【C++】模板(相关知识点讲解 + STL底层涉及的模板应用)
    目录模板是什么?模板格式模板本质函数模板格式介绍显式实例化模板参数匹配原则类模板类模板的实例化非类型模板参数模板特化——概念函数模板特化类模板的特化全特化半特化偏特化三种类特化例子(放一起比较)模板分离编译STL中比较经典的模板应用(不包含argus)......
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——4.模板
    1.泛型编程如何实现一个通用的交换函数呢?voidSwap(int&left,int&right){inttemp=left;left=right;right=temp;}voidSwap(double&left,double&right){doubletemp=left;left=right;right=temp;}voidSwap(char&left,char&right)......
  • Windows图形界面(GUI)-MFC-C/C++ - 树形视图(Tree Control) - CTreeCtrl
    公开视频-> 链接点击跳转公开课程博客首页-> ​​​链接点击跳转博客主页目录树形视图(TreeControl)-CTreeCtrl创建和初始化添加和删除项获取和设置项属性操作项项选择变化项双击项展开示例代码树形视图(TreeControl)-CTreeCtrl创建和初始化Subclas......
  • Windows图形界面(GUI)-MFC-C/C++ - 列表视图(List Control) - CListCtrl
    公开视频-> 链接点击跳转公开课程博客首页-> ​​​链接点击跳转博客主页目录列表视图(ListControl)-CListCtrl创建列表视图设置列表视图属性成员函数注意事项示例代码列表视图(ListControl)-CListCtrl创建列表视图在对话框编辑器中,从工具箱中拖拽一个Li......