首页 > 编程语言 >第4章 decltype说明符(C++11~C++17)

第4章 decltype说明符(C++11~C++17)

时间:2024-09-01 23:47:00浏览次数:4  
标签:11 decltype int auto C++ 说明符 类型 return

第4章 decltype说明符(C++11~C++17)

4.1 回顾typeoftypeid

(1)在C++11标准发布以前,GCC的扩展提供了一个名为typeof的运算符。通过该运算符可以获取操作数的具体类型。typeof是GCC所提供,并非C++标准。

int a = 9;
typeof(a) b = 5;

(2)C++标准还提供了一个typeid运算符来获取与目标操作数类型有关的信息。获取的类型信息会包含在一个类型为std::type_info的对象里。我们可以调用成员函数name获取其类型名,成员函数name返回的类型名在C++标准中并没有明确的规范,所以输出的类型名会因编译器而异。

typeid并不能像typeof那样在编译期就确定对象类型

int a = 9;
qDebug() << typeid(a).name(); // msvc输出int  GCC输出i

4.2 使用delctype说明符

(1)语法

int a = 9;
decltype(a) c = 5; // c推断为int

(2)用于函数模板,结合auto以及后置返回类型,推断返回值类型

C++11之前写法,需要将返回值类型写在typename中,每次调用都要写明返回值类型

//C++11之前
template <typename R, typename T1, typename T2>
R sum(T1 a1, T2 a2)
{
    return a1 + a2;
}

C++11中使用delctype,后置返回类型,使用auto自动推导返回值类型

// C++11
template <typename T1, typename T2>
auto sum(T1 a1, T2 a2) -> decltype(a1 + a2)
{
    return a1 + a2;
}

int main()
{
    auto x = sum(5, 0.5);
}

C++14中,支持对函数返回类型的推导,因此就不用decltype

// C++14
template <typename T1, typename T2>
auto sum(T1 a1, T2 a2)
{
    return a1 + a2;
}

int main()
{
    auto x = sum(5, 0.5);
}

4.3 推导规则

decltype(e)(其中e的类型为T)的推导规则有5条。

1.如果e是一个未加括号的标识符表达式(结构化绑定除外)或者未加括号的类成员访问,则decltype(e)推断出的类型是e的类型T。如果并不存在这样的类型,或者e是一组重载函数,则无法进行推导。

2.如果e是一个函数调用或者仿函数调用,那么decltype(e)推断出的类型是其返回值的类型。

3.如果e是一个类型为T的左值,则decltype(e)是T&。

4.如果e是一个类型为T的将亡值,则decltype(e)是T&&

5.除去以上情况,则decltype(e)T

4.4 cv限定符的推导

通常情况下,decltype(e)所推导的类型会同步e的cv限定符

e是未加括号的成员变量时,父对象表达式的cv限定符会被忽略,不能同步到推导结果。当e是加括号的数据成员时,父对象表达式的cv限定符会同步到推断结果。

4.5 decltype(auto) 【c++14】

在C++14标准中出现了decltypeauto两个关键字的结合体:decltype(auto)。它的作用简单来说,就是告诉编译器用decltype的推导表达式规则来推导auto。另外需要注意的是,decltype(auto)必须单独声明,也就是它不能结合指针、引用以及cv限定符。

使用decltype(auto)消除返回类型后置的语法

template<class T>
auto return_ref(T& t) 
{
    return t;
}

int x1 = 0;
static_assert(std::is_reference_v<decltype(returm_ref(x1)));// 编译错误,因为返回值不为引用类型(auto忽略cv限定符),导致static_assert在编译期报错
template<class T>
auto return_ref(T& t) -> delctype(t)
{
    return t;
}

int x1 = 0;
static_assert(std::is_reference_v<decltype(returm_ref(x1)));// 编译成功
template<class T>
delctype(auto) return_ref(T& t)
{
    return t;
}

int x1 = 0;
static_assert(std::is_reference_v<decltype(returm_ref(x1)));// 编译成功

4.6 decltype(auto)作为非类型模板形参占位符 【c++17】

在C++17标准中decltype(auto)也能作为非类型模板形参的占位符,其推导规则和上面介绍的保持一致

template <decltype(auto) N>
void f()
{
    qDebug() << N;
}

static const int x = 11;
static int y = 7;

int main(int argc, char *argv[])
{
    f<x>();     // 正确
    f<(x)>();   // 正确
    // f<y>();  // y不是编译期常量,编译报错
    f<(y)>();   // (y)是表达式,表达式的值是编译期常量
}

标签:11,decltype,int,auto,C++,说明符,类型,return
From: https://www.cnblogs.com/Danieeel959/p/18391965

相关文章

  • Openshift 3.11单机版 离线安装
    Openshift3.11单机版离线安装‍前置条件虚拟机:建议系统内存>=6G,CPU>=4。镜像仓库:在虚拟机上能够访问到该镜像仓库,如果没有,推荐使用harbor自建。docker:虚拟机上需要安装docker,这里使用的是18.09版本。离线安装可参考docker离线安装或自行下载rpm包安装。‍安装步骤......
  • springboot原创歌曲分享平台(11066)
     有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项......
  • springboot招生管理系统(11071)
     有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项......
  • 中国各地区数字经济发展对环境污染的影响数据(2011-2021年)
    关于中国各地区数字经济发展对环境污染的影响数据(2011-2021年),可以从以下几个方面获取相关信息:数字经济水平:可以通过熵值法衡量的数字经济水平指标来评估各地区的数字经济发展情况。环境污染物排放量:包括PM2.5均值、工业烟粉尘排放量、工业二氧化硫排放量和工业废水排放量等......
  • 深入理解C++中的同步并发操作(c++ concurrency in action 第四章总结)
    深入理解C++中的同步并发操作(c++concurrencyinaction第四章总结)第四章详细介绍了C++中的各种并发工具,包括条件变量、std::future和std::async、带超时的wait、std::packaged_task和std::promise,以及如何使用这些工具来简化代码。本总结将依次介绍这些工具的用法......
  • 深入理解C++中的const:函数参数与成员函数的最佳实践
    const关键字在C++中有多种用途,它的主要作用是定义不可修改的变量或数据,使得代码更加安全和清晰。具体使用场景包括:定义常量变量:使用const定义的变量在初始化后不能被修改。这样可以防止代码中对该变量的意外修改。constintmax_value=100;max_value=200;//错误:尝试......
  • 深度解析:引用 vs 指针,C++程序员必须掌握的核心概念
    引用(Reference)和指针(Pointer)都是C++中非常重要的概念,它们都用于间接访问变量或对象,但在使用方式、语法、内存管理等方面存在显著区别。下面详细解释什么是引用,并展开讨论它与指针的区别。一、什么是引用?引用(Reference)是C++中的一种变量类型,它是已存在变量的一个别名。引用本......
  • C++菜鸟教程 - 从入门到精通 第一节
    一.C++简介C++是一种编程语言,它是由BjarneStroustrup于1979年在贝尔实验室开始设计开发的。C++进一步扩充和完善了C语言,是一种面向对象的程序设计语言。C++可运行于多种平台上,如Windows、MAC操作系统以及 UNIX的各种版本。C++是一种静态类型的、编译式的、......
  • C++头文件<algorithm>中常用函数简介
     概述头文件algorithm(算法库)中主要提供了一些对容器操作的函数,如排序、搜索、复制、比较等,因此使用频率还是很高的,由于主要是操作容器,所以函数的语法也很类似:algorithm_name(container.begin(),container.end(),...);其中,container.begin()和container.end()分......
  • 正点原子Linux C应用编程:移植tslib并使其适配7寸LCD1024*600的GT911触摸驱动
    正点原子LinuxC应用编程:移植tslib并使其适配7寸LCD1024*600的GT911触摸驱动作者在学习【正点原子】I.MX6U嵌入式LinuxC应用编程指南V1.4时,发现移植tslib后,触摸事件触发不正常。使用的硬件版本:正点原子I.MX6UALPHAV2.4版本底板,LCD:正点原子7寸1024*600,型号ATK-MD0700R-102460......