C++ 类型推导Auto及decltype

目录

auto

decltype


decltype 和 auto 是 C++11 及其后续版本中引入的两个关键字,它们都用于自动类型推导,但在使用和行为上有一些重要的区别。

auto

auto 关键字在 C++ 中用于自动类型推导。编译器会根据初始化表达式自动推断变量的类型。auto 关键字使代码更加简洁,因为你不需要显式地写出变量的类型。

auto x = 10; // x 的类型被推导为 int
auto y = 3.14; // y 的类型被推导为 double
auto z = "hello"; // z 的类型被推导为 const char*

auto 关键字在编译时推导变量的类型,并且在推导过程中会考虑引用和 const 限定符。

int a = 10;
auto& b = a; // b 是 int& 类型,对 b 的修改会影响到 a
const auto c = a; // c 是 const int 类型,不能修改 c 的值

除此之外使用 auto 会删除引用、const 限定符和 volatile 限定符,如下面代码会输出什么呢?是11 11?还是11 12?

#include <iostream>using namespace std;int main( )
{int count = 10;int& countRef = count;auto myAuto = countRef;countRef = 11;cout << count << " ";myAuto = 12;cout << count << endl;
}

decltype

下面是decltype的规则,这些规则用于确定表达式的类型:

  1. 如果表达式是一个未加括号的标识符或类成员访问

    • decltype(x) 或 decltype(obj.mem) 的类型是 T,其中 T 是 x 或 mem 的类型。
    • 如果 x 是一个函数名,decltype(x) 是函数类型,而不是函数的返回类型。
    • 如果 x 没有定义,编译器会报错。
  2. 如果表达式是一个函数调用或重载运算符

    • decltype(f()) 或 decltype(operator+()) 的类型是函数的返回类型。
    • 忽略重载运算符两边的括号。
  3. 如果表达式是一个左值

    • decltype((x)) 的类型是 T&,其中 T 是 x 的类型,且 x 是一个左值。
    • 这里的括号是重要的,因为不加括号的话,规则4会应用。
  4. 如果表达式是一个右值

    • decltype(x) 的类型是 T,其中 T 是 x 的类型,且 x 是一个右值。
    • 注意,这与左值引用不同,右值不会获得引用类型。
  5. 引用折叠

    • 如果 decltype 推导出的类型是引用类型(例如 T& 或 T&&),并且这个引用类型被用作模板参数,那么在某些情况下会发生引用折叠(reference collapsing)。
    • 例如,T& &T& &&T&& & 折叠为 T&,而 T&& && 折叠为 T&&
  6. **对于 decltype(auto)**:

    • 在C++14及以后的版本中,decltype(auto) 允许编译器自动推导变量类型,并保留表达式的值类别。
    • 例如,decltype(auto) x = y; 将根据 y 的类型(及其值类别)来推导 x 的类型。
int var;
const int&& fx();
struct A { double x; };
const A* a = new A();
语句类型说明
decltype(fx());const int&&对 const int 的 rvalue 引用。
decltype(var);int变量 var 的类型。
decltype(a->x);double成员访问的类型。
decltype((a->x));const double&内部括号导致语句作为表达式而不是成员访问计算。 由于 a 声明为 const 指针,因此类型是对 const double 的引用。

 作为函数模版应用

// decltype_1.cpp
// compile with: cl /EHsc decltype_1.cpp#include <iostream>
#include <string>
#include <utility>
#include <iomanip>using namespace std;template<typename T1, typename T2>
auto Plus(T1&& t1, T2&& t2) ->decltype(forward<T1>(t1) + forward<T2>(t2))
{return forward<T1>(t1) + forward<T2>(t2);
}class X
{friend X operator+(const X& x1, const X& x2){return X(x1.m_data + x2.m_data);}public:X(int data) : m_data(data) {}int Dump() const { return m_data;}
private:int m_data;
};int main()
{// Integerint i = 4;cout <<"Plus(i, 9) = " <<Plus(i, 9) << endl;// Floating pointfloat dx = 4.0;float dy = 9.5;cout <<setprecision(3) <<"Plus(dx, dy) = " <<Plus(dx, dy) << endl;// Stringstring hello = "Hello, ";string world = "world!";cout << Plus(hello, world) << endl;// Custom typeX x1(20);X x2(22);X x3 = Plus(x1, x2);cout <<"x3.Dump() = " <<x3.Dump() << endl;
}

当模板被声明而不是被实例化时,编译器会分析 decltype 自变量。 因此,如果在 decltype 自变量中找到非依赖专用化,则它不会被推迟到实例化时间;而是被立即处理,并且在当时诊断产生的所有错误。

以下示例显示了在声明时引发的这类编译器错误:

#include <utility>
template <class T, class ReturnT, class... ArgsT> class IsCallable
{
public:struct BadType {};template <class U>static decltype(std::declval<T>()(std::declval<ArgsT>()...)) Test(int); //C2064. Should be declval<U>template <class U>static BadType Test(...);static constexpr bool value = std::is_convertible<decltype(Test<T>(0)), ReturnT>::value;
};constexpr bool test1 = IsCallable<int(), int>::value;
static_assert(test1, "PASS1");
constexpr bool test2 = !IsCallable<int*, int>::value;
static_assert(test2, "PASS2");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/810707.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

切面条(蓝桥杯)

目录 题目 分析 代码实现 题目 一根高筋拉面&#xff0c;中间切一刀&#xff0c;可以得到2根面条。 如果先对折1次&#xff0c;中间切一刀&#xff0c;可以得到3根面条。 如果连续对折2次&#xff0c;中间切一刀&#xff0c;可以得到5根面条。 那么&#xff0c;连续对折1…

光耦合器的使用:了解输入和输出之间的关系

光耦合器也称为光隔离器&#xff0c;是许多电子电路中的重要组件&#xff0c;可在输入和输出信号之间提供隔离。它们在各种应用中确保安全、降低噪声和防止接地环路方面发挥着至关重要的作用。在本文中&#xff0c;我们将深入研究光耦合器的基础知识&#xff0c;探讨它们的工作…

人形机器人行业报告:AI赋能人形机器人开启产业化元年

今天分享的是人形机器人专题系列深度研究报告&#xff1a;《AI赋能&#xff0c;人形机器人开启产业化元年》。 &#xff08;报告出品方&#xff1a;国泰君安证券&#xff09; 报告共计&#xff1a;56页 要点 通用性是人形机器人商业化的关键&#xff0c;AI大模型赋能加速机…

打破传统,蔚莱普康定义国货美妆新未来

在全球美妆市场经济改革的今天&#xff0c;中国新兴品牌蔚莱普康&#xff0c;正在以前所未有的速度和规模&#xff0c;冲破瓶颈&#xff0c;赢得市场的广泛认可。这一切&#xff0c;得益于国家政策的扶持和国货品牌自身的不懈努力与创新。 各类国潮产品不断‘出圈’的背后&…

java程序 .exe启动nginx防止重复启动,已解决

java代码生成好的.exe启动nginx服务程序 根据nginx占用端口来解决nginx服务重复启动问题&#xff08;下面代码了解代码逻辑后根据自己的业务需求修改即可&#xff09; 代码&#xff1a; package org.example;import javax.swing.*; import java.awt.*; import java.io.*; …

Linux-select剖析

一、select函数 select函数是IO多路复用的函数&#xff0c;它主要的功能是用来等文件描述符中的事件是否就绪&#xff0c;select可以使我们在同时等待多个文件缓冲区 &#xff0c;减少IO等待的时间&#xff0c;能够提高进程的IO效率。 select()函数允许程序监视多个文件描述符…

书生·浦语大模型全链路开源体系-第3课

书生浦语大模型全链路开源体系-第3课 书生浦语大模型全链路开源体系-第3课相关资源RAG 概述在 InternLM Studio 上部署茴香豆技术助手环境配置配置基础环境下载基础文件下载安装茴香豆 使用茴香豆搭建 RAG 助手修改配置文件 创建知识库运行茴香豆知识助手 在茴香豆 Web 版中创建…

工作日常随记-总

软件测试主管工作日常随记-总 前言 接下来&#xff0c;我将开始散文式地记录我作为一位从业3年多的软件测试人员的软测经验。这是我在繁忙的日常工作的中跋涉出来又又投入的另一工作&#xff08;bushi&#xff09;另一兴趣中去。 我将简单&#xff08;偏流水线向&#xff09;…

50. QT/QML中创建多线程的方式汇总

1. 说明 在QT / QML中创建线程主要有三种方式。第一种:在定义类时继承 QThread 这个类,然后重写父类的虚函数 run(),将子线程需要执行的业务代码放到 run() 函数当中即可。**注意:**这种方式官方已经摒弃了。第二种:使用moveToThread()函数将需要在子线程中执行的函数类移…

Docker搭建Deluge

Deluge 是一个开源的跨平台 BitTorrent 客户端&#xff0c;具有轻量级、功能强大、易于使用的特点。通过 Docker 镜像&#xff0c;您可以轻松地部署 Deluge 在您的服务器上&#xff0c;用于下载和管理 BitTorrent 文件。 步骤一&#xff1a;使用 Docker CLI 搭建 Deluge 拉取 …

【每日练习】二叉树

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;二叉树 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 文章目录 一、100. 相同的树1. 题目简介2.…

问题汇总

一、TCP的粘包和拆包问题&#xff1f; TCP在发送和接受数据的时候&#xff0c;有一个滑动窗口来控制接受数据的大小&#xff0c;这个滑动窗口你就可以理解为一个缓冲区的大小。缓冲区满了就会把数据发送&#xff0c;数据包的大小是不固定的&#xff0c;有时候比缓冲区大有时候…

python学习面向对象之组合的那些事儿

先上概念&#xff1a; 组合是通过将不同的类或模块组合在一起&#xff0c;创建一个新的类来实现的机制。这意味着一个类的对象可以包含其他类的对象作为其部分&#xff0c;通过组合这些部分来实现整体的功能。 交通工具的烦恼 话说时间到3030年了&#xff0c;风陵苑交通协会…

NIST再次强调:2024-2030年,必须升级至抗量子算法

4月10日至12日&#xff0c;美国国家标准与技术研究院&#xff08;NIST&#xff09;在马里兰州罗克维尔举办第五届NIST PQC&#xff08;后量子密码学&#xff09;标准化会议&#xff0c;该会议的目的是对PQC算法进行全面讨论&#xff08;包括已选定和正在评估的算法&#xff09;…

如何处理ubuntu22.04LTS安装过程中出现“Daemons using outdated libraries”提示

Ubuntu 22.04 LTS 中使用命令行升级软件或安装任何新软件时&#xff0c;您可能收到“Daemons using outdated libraries”&#xff0c;“Which services should be restarted?”的提示&#xff0c;提示下面列出备选的重启服务&#xff0c;如下。 使用以下命令&#xff0c;能够…

LangChain - 文档加载

文章目录 一、关于 检索二、文档加载器入门指南 三、CSV1、使用每个文档一行的 CSV 数据加载 CSVLoader2、自定义 csv 解析和加载 &#xff08;csv_args3、指定用于 标识文档来源的 列&#xff08;source_column 四、文件目录 file_directory1、加载文件目录数据&#xff08;Di…

day05-java面向对象(上)

5.1 面向对象编程 5.1.1 类和对象 1、什么是类 类是一类具有相同特性的事物的抽象描述&#xff0c;是一组相关属性和行为的集合。 属性&#xff1a;就是该事物的状态信息。 行为&#xff1a;就是在你这个程序中&#xff0c;该状态信息要做什么操作&#xff0c;或者基于事物…

Go操作Kafka之kafka-go

Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;本文介绍了如何使用kafka-go这个库实现Go语言与kafka的交互。 Go社区中目前有三个比较常用的kafka客户端库 , 它们各有特点。 首先是IBM/sarama&#xff08;这个库已经由Shopify转给了IBM&#xff09;&#xff0c;之…

Triton Server Python 后端优化

接上文 不使用 Docker 构建 Triton 服务器并在 Google Colab 平台上部署 HuggingFace 模型 MultiGPU && Multi Instance Config 追加 instance_group [{count: 4kind: KIND_GPUgpus: [ 0, 1 ]} ]Python Backend Triton 会根据配置信息启动四个实例&#xff0c;…

物联网数据服务平台

随着物联网技术的迅猛发展&#xff0c;海量数据的产生和应用成为推动工业数字化转型的核心动力。在这个数据为王的时代&#xff0c;如何高效地收集、处理、分析并应用这些数据&#xff0c;成为了企业关注的焦点。物联网数据服务平台应运而生&#xff0c;为企业提供了全面、高效…