C++的std::is_same与std::decay

2023-11-06

一、背景

有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是int型还是double型呢?

#include <iostream>
template<typename T>

void typeCheck(T data)
{
    // check data type
    //std::cout<< out put the type
}

二、std::is_same

<type_traits>头文件中提供了C++ STL的std::is_same模板。 C++ STL的std::is_same模板用于检查类型A是否与类型B相同。如果两者相同,则返回布尔值true,否则返回false。

模板类型

template <class A, class B>
struct is_same

template <class A, class B>
inline constexpr 
       bool is_same_v
         = is_same<A, B>::value

用法

std::is_same<A, B>::value

实例

#include <iostream>
#include <type_traits>
#include <cstdint>

int main()
{
    //使bool型变量按照false、true的格式输出。
    //如不使用该标识符,那么结果会按照1、0的格式输出。
    std::cout << std::boolalpha;

    // usually true if 'int' is 32 bit
    std::cout << std::is_same<int, std::int32_t>::value << ' '; // ~ true
    std::cout << std::is_same<int, std::int64_t>::value << ' '; // ~ false

    // same tests as above, except using C++17's `std::is_same_v<T, U>` format
    std::cout << std::is_same_v<int, std::int32_t> << ' ';  // ~ true
    std::cout << std::is_same_v<int, std::int64_t> << '\n'; // ~ false

    // compare the types of a couple variables
    long double num1 = 1.0;
    long double num2 = 2.0;
    std::cout << std::is_same_v<decltype(num1), decltype(num2)> << '\n'; // true

    // 'float' is never an integral type
    std::cout << std::is_same<float, std::int32_t>::value << '\n'; // false

    // 'int' is implicitly 'signed'
    std::cout << std::is_same<int, int>::value << ' ';          // true
    std::cout << std::is_same<int, unsigned int>::value << ' '; // false
    std::cout << std::is_same<int, signed int>::value << '\n';  // true

    system("pause");
    return 0;

}

打印

 

四、新的问题

std::is_same可以判断两种类似是否一样,那么用在模板里就是利器了,比如直接在编译的时候判断类型

#include <iostream>
template<typename TYPE>
typeCheck(TYPE data)
{
    if(std::is_same<TYPE,int>::value)
    {
        std::cout<<"int type";
        //do something int 
    }
    else
    {
        //.........
    }
}

让我们试一试

// is_same example
#include <iostream>
#include <type_traits>
#include <cstdint>

typedef int integer_type;

struct A { 
    int x;
    int y;
};

struct B { 
int x;
int y; 
};

typedef A C;

int main() {
      std::cout << std::boolalpha;
      std::cout << "is_same:" << std::endl;
      std::cout << "int, const int: " << std::is_same<int, const int>::value << std::endl;//false
      std::cout << "int, int&: " << std::is_same<int, int&>::value << std::endl;//false
      std::cout << "int, const int&: " << std::is_same<int, const int&>::value << std::endl;//false
      std::cout << "int, integer_type: " << std::is_same<int, integer_type>::value << std::endl;//true
      std::cout << "A, B: " << std::is_same<A,B>::value << std::endl;//false
      std::cout << "A, C: " << std::is_same<A,C>::value << std::endl;//true
      std::cout << "signed char, std::int8_t: " << std::is_same<signed char,std::int8_t>::value << std::endl;//true
      return 0;
}

打印

发现std::is_same的判断是很严格的.std::is_same对int和const int\int &\const int&等都是区别对待的,但在写模板函数时,经常会强制指定常引用进行传参,以免进行数据拷贝,这时候is_same就做出了不相等的判断,但是有时候其实我们还是希望TYPE和const TYPE& 是能认为是一样的,这时就需要std::decay进行退化处理。
 

四、std::decay

C++11提供了一个模板类,来为我们移除类型中的一些特性,比如引用、常量、volatile,但是注意不包括指针特性。std::decay 对一个类型进行退化处理,它的实现如下

template< class T >
struct decay {
private:
    typedef typename std::remove_reference<T>::type U;
public:
    typedef typename std::conditional< 
        std::is_array<U>::value,
        typename std::remove_extent<U>::type*,
        typename std::conditional< 
            std::is_function<U>::value,
            typename std::add_pointer<U>::type,
            typename std::remove_cv<U>::type
        >::type
    >::type type;
};

 实例

#include <iostream>
#include <type_traits>

template <typename T, typename U>
struct decay_equiv : 
    std::is_same<typename std::decay<T>::type, U>::type 
{};

int main()
{
    std::cout << std::boolalpha
              << decay_equiv<int, int>::value << '\n'
              << decay_equiv<int&, int>::value << '\n'
              << decay_equiv<int&&, int>::value << '\n'
              << decay_equiv<const int&, int>::value << '\n'
              << decay_equiv<int[2], int*>::value << '\n'
              << decay_equiv<int(int), int(*)(int)>::value << '\n';
    return 0;
}

打印

 

参考:

C++11的模板类型判断——std::is_same和std::decay_尘中远的博客-CSDN博客_std::decay

std::is_same - cppreference.com

std::decay - cppreference.com

【C++11】C++类型完全退化(拓展std::decay的功能)_几罗星人的博客-CSDN博客_std::decay

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++的std::is_same与std::decay 的相关文章

  • setContextProperty 和对象的 setProperty 之间的区别

    我现在真的很困惑 有什么区别 QQmlApplicationEngine engine engine rootContext setContextProperty myObject userData and object gt setPro
  • 将图像文件从网址复制到本地文件夹?

    我有该图像的网址 例如 http testsite com web abc jpg http testsite com web abc jpg 我想将该 URL 复制到 c images 中的本地文件夹中 而且当我将该文件复制到文件夹中时
  • 使用API​​隐藏程序标题栏

    它可以使用 c 和 windows api 删除窗口控制台标题栏 如果是的话如何 请 这个简单的应用程序隐藏并显示其所在控制台的标题栏 它会立即将控制台标题更改为 guid 以查找窗口句柄 然后 它使用 ToggleTitleBar 使用找
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • 在Application_AquireRequestState事件中用POST数据重写Url

    我有一个在其中注册路线的代码Application AcquireRequestState应用程序的事件 注册路由后 我会在 Http 运行时缓存中设置一个标志 这样我就不会再次执行路由注册代码 在此事件中注册路线有特定原因Applicat
  • 静态类变量与外部变量相同,只是具有类作用域吗?

    在我看来 静态类变量与外部变量相同 因为你只需要declare它在static int x extern int x语句 并在其他地方实际定义它 通常在 cpp 文件中 静态类变量 h file class Foo static int x
  • Paradox 表 - Oledb 异常:外部表不是预期的格式

    我正在使用 Oledb 从 Paradox 表中读取一些数据 我遇到的问题是 当我将代码复制到控制台应用程序时 代码可以工作 但在 WinForms 中却不行 两者都以 x86 进行调试 我实际上只是复制代码 在 WinForms 应用程序
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 如何使用 wpf webbrowser 将数据发布到 Web 服务器

    我想从数据库获取数据并使用它来让用户登录到网站 我有一个包含 Web 浏览器控件的 wpf 页面 我有这样的代码 用于将用户登录到用 php 编写的网站
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • 防止GDB中的PLT(过程链接表)断点

    在最新版本的 GDB 中 在库函数调用上设置断点会导致多个实际断点 调用过程链接表 PLT 实际的函数调用 这意味着当调用库函数时 我们每次都会经历两次中断 在以前的 GDB 版本中 只会创建 2 因此您只能得到一次中断 那么问题来了 是否
  • 格式化货币

    在下面的示例中 逗号是小数点分隔符 我有这个 125456 89 我想要这个 125 456 89 其他示例 23456789 89 gt 23 456 789 89 Thanks 看看这个例子 double value 12345 678
  • 更改 IdentityServer4 实体框架表名称

    我正在尝试更改由 IdentityServer4 的 PersistedGrantDb 和 ConfigurationDb 创建的默认表名称 并让实体框架生成正确的 SQL 例如 而不是使用实体IdentityServer4 EntityF
  • C#中Enum中定义的value__是什么

    What value 可能在这里 value MSN ICQ YahooChat GoogleTalk 我运行的代码很简单 namespace EnumReflection enum Messengers MSN ICQ YahooChat
  • dropdownlist DataTextField 由属性组成?

    有没有一种方法可以通过 C 使 asp net 中的下拉列表的 datatextfield 属性由对象的多个属性组成 public class MyObject public int Id get set public string Nam
  • 系统错误 124 - SHFileOperation 的 ERROR_INVALID_LEVEL

    我在使用时遇到问题SHFileOperation SHFileOperation SHFILEOPSTRUCT https stackoverflow com questions 9191415 shfileoperation shfile
  • 设计 Javascript 前端 <-> C++ 后端通信

    在我最近的将来 我将不得不制作一个具有 C 后端和 Web 前端的系统 要求 目前 我对此了解不多 我认为前端将触发数据传输 而不是后端 所以不需要类似 Comet 的东西 由于在该领域的经验可能很少 我非常感谢您对我所做的设计决策的评论
  • 使用 foreach 循环和 XmlNodeList C# 将新节点附加到节点列表

    目前我处理的是这样的XML类型 XML FILE http 20drive google com open id 0By5BxgNi9eGcRldxcEZNU0FDTzQ 参考XML文件 我想检查一个节点 如果找不到该节点 我必须将该节点附
  • 从 C 线程调用 Python 代码

    我对从 C 或 C 线程调用 Python 代码时如何确保线程安全感到非常困惑 The Python 文档 http docs python org c api init html non python created threads似乎是
  • 纯虚函数可能没有内联定义。为什么?

    纯虚函数是那些虚函数并且具有纯说明符 0 第 10 4 条第 2 款C 03 的内容告诉我们什么是抽象类 顺便说一句 如下 注意 函数声明不能 同时提供纯说明符和定义 尾注 示例 struct C virtual void f 0 ill

随机推荐

  • 模式识别(1)协方差矩阵相关和K-means聚类算法实现(含源码)

    模式识别实验一 实验一 协方差矩阵和矩阵特征值 特征向量的计算 题目简介 给定一组数据 实现该组数据的协方差矩阵的计算 并用代码实现计算一个方阵的特征值和特征向量 一 协方差部分 1 协方差的定义 协方差在概率论和统计学中用于衡量两个变量的
  • java-maven的使用

    一 加载maven项目 1 idea工具栏file open 选择项目加载进来 2 右键pom xml 选择add as maven project 3 如果在pom xml上的某个依赖一直报红且依赖本身没有问题 本pom其他的依赖也没有问
  • 面试概率题目

    概率题目 现在的面试中 大部分公司都会问道概率相关的问题 我们现在给出几道常见的概率问题 1 三角形问题 题目 给你一根铅笔 将铅笔折两次 组成三角形的概率是多大 解析 设 铅笔长度是1 折两次之后 得到三条边 对应的长度分别是x y 1
  • css3实现动画的三种方式

    css实现动画主要有3种方式 第一种是 transition实现渐变动画 第二种是 transform转变动画 第三种是 animation实现自定义动画 transition渐变动画 过渡 语法格式 transition 要过渡的属性 花
  • win10 凭据管理

    点击WIN10左下角的开始选项 选择所有程序 找到WINDOWS系统 点开找到控制面板 打开控制面板 找到里面的 凭据管理器 打开凭据管理器 找到 WINDOWS凭据 然后点击 添加WINDOWS凭据 进入凭据添加页面 添加WINDOWS凭
  • 图像分割中的损失函数

    图像分割中的损失函数 文章目录 图像分割中的损失函数 前言 一 交叉熵损失 二 Dice loss 三 Focal loss 四 IOU损失函数 总结 前言 在深度学习中 所有算法都依赖于最小化或最大化一个函数 称之为损失函数 损失函数用于
  • 蓝桥杯基础练习(1)---数列排序

    一 数列排序问题的解决 问题描述 给定一个长度为n的数列 将这个数列按从小到大的顺序排列 1 lt n lt 200 输入格式 第一行为一个整数n 第二行包含n个整数 为待排序的数 每个整数的绝对值小于10000 输出格式 输出一行 按从小
  • 全球13台DNS根服务器分布:

    全球13台DNS根服务器分布 美国VeriSign公司 2台 网络管理组织IANA Internet Assigned Number Authority 1台 欧洲网络管理组织RIPE NCC Resource IP Europeens N
  • 解决curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused 问题

    自动化使用要去下载图像识别的工具 Tesseract mac 需要用到brew 但是我的电脑没有 就先需要下载homebrew 然而按照官网的命令 bin bash c curl fsSL https raw githubuserconte
  • 将一个链表分为奇偶两个链表

    1 问题描述 设计一个算法 将一个头结点为A的单链表 其数据域为整数 分解成两个单链表A和B 使得A链表只含有原来链表data域为奇数的节点 而B链表只含有原链表中data域为偶数的节点 而且保持原来的顺序 2 思路分析 这个问题不是在线网
  • python pandas.set_option()详解

    一 简介 set option是pandas里的一个函数 用法为pandas set option pat value 主要作用是设置一些指定参数的值 供设置的选项如下 后面会逐一进行介绍 compute use bottleneck us
  • python研究生导师_研究生导师布置的作业!利用Python和API收集与分析网络数据!...

    猜猜看 下面这一组调查对象是什么 为什么会这样呢 因为我在布置作业的时候 很贴心地给了一个样例 是我之前写的一篇教程 如何用R和API免费获取Web数据 于是 多组作业 都雷同 讲到这里 他们一副不好意思的表情 我却发觉 这里蕴藏着一个问题
  • 上传文件,提交数据---FormData对象格式

    上传文件 提交数据 FormData对象格式 在进行上传文件 例如Excel 时 处理的几步 否则无法上传 一 修改请求头 在修改请求头 是至关重要的 因为请求数据格式是不同的 header multipart form data 注 在写
  • 4- OpenCV+TensorFlow 入门人工智能图像处理-灰度化处理

    图片特效及线段文字的绘制 特效1 灰度处理 mark 完成彩色图片灰度化 彩色图片有三个颜色通道RGB 灰度图片也是三通道的话 RGB值相等 单通道的灰度图片的值 需要经过RGB值进行计算 图中两个公式 一个是取均值 一个是根据公式 特效2
  • OD-求字符串中所有整数的最小和(Python)

    题目描述 说明 字符串s 只包含 a z A Z 合法的整数包括 1 正整数 一个或者多个0 9组成 如 0 2 3 002 102 2 负整数 负号 开头 数字部分由一个或者多个0 9组成 如 0 012 23 00023 输入描述 包含
  • 华为云DevCloud平台部署bootdo博客论坛实战【开发者专属集市】

    华为云DevCloud平台部署bootdo博客论坛实战 开发者专属集市 一 bootdo blog开源博客介绍 二 本次实践所用工具及平台 三 购买华为RDS数据库 1 购买RDS数据库 2 查看RDS数据库状态 四 创建项目 1 登录华为
  • sqli-labs通关记录

    sqli lab通关记录 docker搭建 运行 docker info 查看docker信息 确认docker正常 搜索sqli labs docker search sqli labs 建立镜像 docker pull acgpiano
  • sharding-jdbc 分库分表配置方案

    Java配置 Yaml配置 Spring Boot配置 Spring命名空间配置 http shardingsphere io document current cn manual sharding jdbc configuration c
  • 【送书活动】AI时代,程序员需要焦虑吗?

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 React从入门到精通 前端炫酷代码分享 从0到英雄 vue成神之路 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架
  • C++的std::is_same与std::decay

    一 背景 有一个模板函数 函数在处理int型和double型时需要进行特殊的处理 那么怎么在编译期知道传入的参数的数据类型是int型还是double型呢 include