当前位置: 首页 > news >正文

C++新经典模板与泛型编程:SFINAE特性的信息萃取

用成员函数重载实现is_default_constructible

首先介绍一个C++标准库提供的可变参类模板std::is_default_constructible。这个类模板的主要功能是判断一个类的对象是否能被默认构造(所谓默认构造,就是构造一个类对象时,不需要给该类的构造函数传递任何参数)。例如,有一个类A和一个类B,代码如下。

#include "killCmake.h"#include<string>
using namespace std;class A {
};class B
{
public:B(int tmpval) {}
};int main()
{A a_obj;// E0291: 类 "B" 不存在默认构造函数B b_obj;// 要构造类B对象,必须给类B的构造函数提供一个参数B b_obj(1);return 0;
}

现在,可以使用std::is_default_constructible判断类A和类B对象是否能被默认构造(该类没有构造函数或有一个不带参数的构造函数)。在main()主函数中添加代码:

#include "killCmake.h"#include<string>using namespace std;class A {
};class B
{
public:B(int tmpval) {}
};int main()
{std::cout << std::is_default_constructible<int>::value << std::endl;std::cout << std::is_default_constructible<double>::value << std::endl;std::cout << std::is_default_constructible<A>::value << std::endl;std::cout << std::is_default_constructible<B>::value << std::endl;return 0;
}

在这里插入图片描述

  • 从结果中可以看到,int、double等基本类型(内部类型)对象以及类A对象都是可以默认构造的(结果为1),而类B对象因为其构造函数带一个形参(该形参没有默认值),所以无法默认构造。

  • 在明白了std::is_default_constructible的功能后,现在就来深入了解一下它的实现源码。

  • 如果让你来实现一个与std::is_default_constructible同样的功能,借此看一看如何使用SFINAE特性萃取一些重要信息(这里要萃取的信息是判断某个类是否“没有构造函数或有一个不带参数的构造函数”,满足这个条件的类就能够默认构造)。IsDefConstructible类模板的代码如下。

template<typename T>
class IsDefConstructible
{
private:template<typename  = decltype(T())>static std::true_type test(void*);template<typename = int>static std::false_type test(...);public:static constexpr bool value = IsSameType<decltype(test(nullptr)), std::true_type>::value;
};
  • (1)有两个同名的静态成员函数模板test()。注意观察,第1个test()的返回类型是std::true_type,而第2个test()的返回类型是std::false_type。第1个test()的形参是void*,而第2个test()的形参是3个点(…),这个形参读者应该不陌生,是C语言中的省略号形参,代表它可以接受0到任意多个实参。
    尤其要注意第1个和第2个test()的模板参数,都有默认值,第1个test()的模板默认值比较关键(decltype(T())),要重点留意。两个test()都只有声明而没有实现体,因为做类型推断一类事物(一般涉及decltype)的时候往往不需要具体的实现。
  • (2)对于这两个test()静态成员函数(重载函数),调用的时候,编译器会优先选择有具体形参的test()版本,只有该test()版本不匹配时才会选择带省略号形参的test()版本(带省略号的形参具有最低的匹配优先级)。换句话说,优先匹配第1个test()版本,只有第1个test()版本不匹配时,才会去匹配第2个test()版本。
  • (3)最关键的是静态成员变量value的取值,value的最终取值是一个布尔值true(1)或false(0)。如果value最终取值为1,就表示通过模板参数传递给IsDefConstructible的类对象能默认构造,如果value最终取值为0,就表示通过模板参数传递给IsDefConstructible的类对象不能默认构造。
  • 看一看value的最终取值是经过怎样的计算得到的,也就是重点分析下面这行代码:
IsSameType< decltype(test(nullptr)), std::true_type>::value;
  • 上面这行代码用前面讲过的IsSameType<…>::value判断decltype(test(nullptr))和std::true_type这两个类型是否相等,如果相等就返回true,否则返回false。
  • 重点就是代码段decltype(test(nullptr)),这段代码利用decltype判断test()函数的返回类型:如果传递给IsDefConstructible的类型T支持默认构造,那么显然编译器会选择第1个test()并通过decltype推导出返回类型为std::true_type,从而使IsSameType<…>::value返回true;如果传递给IsDefConstructible的类型T不支持默认构造,那么第1个test()就不会成立(因其类型模板参数的默认值不支持类型T的默认构造导致decltype(T())的写法根本就不成立),根据SFINAE特性,编译器会选择第2个test(),然后通过decltype推导出返回类型为std::false_type,从而使IsSameType<…>::value返回false。
  • 以上就是IsDefConstructible类模板的实现细节。现在,可以对main()主函数的代码行进行修改,测试IsDefConstructible类模板能否正常工作。

相关文章:

C++新经典模板与泛型编程:SFINAE特性的信息萃取

用成员函数重载实现is_default_constructible 首先介绍一个C标准库提供的可变参类模板std::is_default_constructible。这个类模板的主要功能是判断一个类的对象是否能被默认构造&#xff08;所谓默认构造&#xff0c;就是构造一个类对象时&#xff0c;不需要给该类的构造函数…...

java单人聊天

服务端 package 单人聊天;import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import…...

nodejs环境安装

node安装 wget https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/v20.8.0/node-v20.8.0-linux-x64.tar.gz tar xf node-v20.8.0-linux-x64.tar.xz -C /usr/local/ ln -s node-v20.8.0-linux-x64 nodevim /etc/profile.d/node.sh export PATH$PATH:/usr/local/node/binnp…...

R语言进行正态分布检验

查了很多资料&#xff0c;还是比较模糊 Kolmogorov-Smirnov检验&#xff08;K-S检验&#xff09;广泛用于正态性检验和其他分布的拟合检验。适用于中等到大样本。 Lilliefors检验是K-S检验的一种变体&#xff0c;专门为小样本设计。其通过使用更准确的临界值来提高对小样本的适…...

什么是SPA(Single Page Application)?它的优点和缺点是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…...

由于找不到xinput1_3.dll,无法继续执行代码的多种解决方法指南,xinput1_3.dll文件修复

当玩家或用户在启动某些游戏和应用程序时&#xff0c;可能会遭遇到一个系统错误提示&#xff1a;“由于找不到xinput1_3.dll,无法继续执行代码l”。这种情况通常指出系统中DirectX组件存在问题。以下我们将介绍几种常用的解决方法&#xff0c;并提供详细的操作步骤。 一.找不到…...

Vue---Echarts

项目需要用echarts来做数据展示&#xff0c;现记录vue3引入并使用echarts的过程。 1. 使用步骤 安装 ECharts&#xff1a;使用 npm 或 yarn 等包管理工具安装 ECharts。 npm install echarts 在 Vue 组件中引入 ECharts&#xff1a;在需要使用图表的 Vue 组件中&#xff0c;引入…...

uni-app实现返回刷新上一页

方案一 通过监听器实现 page1 uni.$on("refresh", function(data) {if(data.page "page2") {this.reload()} })page2 methods: {handleBack() {uni.$emit("refresh", {page: "page2"})uni.navigateBack()} }方案二 通过页面实例实…...

centos服务器安装docker和Rabbitmq

centos服务器 一 centos安装docker1 安装docker所需要的依赖包2配置yum源3查看仓库中所有的docker版本4安装docker5 设置docker为开机自启6验证docker是否安装成功 二 使用docker安装RabbitMQ拉取RabbitMQ镜像创建并运行容器 一 centos安装docker 1 安装docker所需要的依赖包 …...

【Redis】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)

目录 Redis的慢查询 慢查询配置 慢查询操作命令 慢查询建议 Pipeline 事务 Redis的事务原理 Redis的watch命令 Pipeline和事务的区别 Lua Lua入门 安装Lua Lua基本语法 注释 标示符 关键词 全局变量 Lua中的数据类型 Lua 中的函数 Lua 变量 Lua中的控制语句…...

【pytorch】深度学习入门一:pytorch的安装与配置(Windows版)

请支持原创&#xff0c;认准DannisTang&#xff08;tangweixuan1995foxmail.com&#xff09; 文章目录 第〇章 阅读前提示第一章 准备工作第一节 Python下载第二节 Python安装第三节 Python配置第四节 Pycharm下载第五节 Pycharm安装第六节 CUDA的安装 第二章 Anaconda安装与配…...

安装postgresql驱动及python使用pyodbc指定postgresql驱动调用postgresql

注&#xff1a;Python解释器版本(32位/64位)和postgresql驱动版本(32位/64位)需一致。 一、安装postgresql驱动 https://www.postgresql.org/ftp/odbc/versions/msi/ &#xff08;1&#xff09;32位&#xff1a; &#xff08;2&#xff09;64位&#xff1a; 双击安装。全程默…...

【OpenCV】计算机视觉图像处理基础知识

目录 前言 推荐 1、OpenCV礼帽操作和黑帽操作 2、Sobel算子理论基础及实际操作 3、Scharr算子简介及相关操作 4、Sobel算子和Scharr算子的比较 5、laplacian算子简介及相关操作 6、Canny边缘检测的原理 6.1 去噪 6.2 梯度运算 6.3 非极大值抑制 6.4 滞后阈值 7、Ca…...

Course1-Week3-分类问题

Course1-Week3-分类问题 文章目录 Course1-Week3-分类问题1. 逻辑回归1.1 线性回归不适用于分类问题1.2 逻辑回归模型1.3 决策边界 2. 逻辑回归的代价函数3. 实现梯度下降4. 过拟合与正则化4.1 线性回归和逻辑回归中的过拟合4.2 解决过拟合的三种方法4.3 正则化4.4 用于线性回归…...

Dockerfile 指令的最佳实践

这些建议旨在帮助您创建一个高效且可维护的Dockerfile。 一、FROM 尽可能使用当前的官方镜像作为镜像的基础。Docker推荐Alpine镜像&#xff0c;因为它受到严格控制&#xff0c;体积小&#xff08;目前不到6 MB&#xff09;&#xff0c;同时仍然是一个完整的Linux发行版。 FR…...

Drools 入门:折扣案例

1. 安装 在idea软件中安装Drools 插件&#xff0c;我这里是直接搜索Drools就可以搜到 2. 实现入门案例 2.1 配置pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&q…...

微信小程序中生命周期钩子函数

微信小程序 App 的生命周期钩子函数有以下 7 个&#xff1a; onLaunch(options)&#xff1a;当小程序初始化完成时&#xff0c;会触发 onLaunch&#xff08;全局只触发一次&#xff09;。onShow(options)&#xff1a;当小程序启动或从后台进入前台显示时&#xff0c;会触发 on…...

“无忧文件安全!上海迅软DSE文件加密软件助您轻松管控分公司数据!

许多大型企业集团由于旗下有着分布在不同城市的分支机构&#xff0c;因此在规划数据安全解决方案时&#xff0c;不适合采用市面上常见的集中式部署方式来管控各分部服务器&#xff0c;而迅软DSE文件加密软件支持采用分布式部署的方式来解决这一问题。 企业用户只需在总部内部署…...

详解线段树

前段时间写过一篇关于树状数组的博客树状数组&#xff0c;今天我们要介绍的是线段树&#xff0c;线段树比树状数组中的应用场景更加的广泛。这些问题也是在leetcode 11月的每日一题频繁遇到的问题&#xff0c;实际上线段树就和红黑树 、堆一样是一类模板&#xff0c;但是标准库…...

C语言——指针的运算

1、指针 - 整数 #include<stdio.h> #define N_VALUES 5 int main() {flout values[N_VALUES];flout *vp;for(vp&values[0];vp<&values[N_VALUES]&#xff1b;) //指针的关系运算{*vp0; //指针整数} } 2、指针 - 指针 #include<stdio.h> int main() …...

Apache Hive(部署+SQL+FineBI构建展示)

Hive架构 Hive部署 VMware虚拟机部署 一、在node1节点安装mysql数据库 二、配置Hadoop 三、下载 解压Hive 四、提供mysql Driver驱动 五、配置Hive 六、初始化元数据库 七、启动Hive(Hadoop用户) chown -R hadoop:hadoop apache-hive-3.1.3-bin hive 阿里云部…...

python入门级简易教程

Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它是一种通用的、解释型的、高级的、动态的、面向对象的编程语言。 Python的编程哲学是简洁明了&#xff0c;强调代码的可读性和简洁性&#xff0c;使开发人员能够快速开发出正确的代码。Python被广泛用…...

模拟一个集合 里面是设备号和每日的日期

问题&#xff1a; 需要模拟一个集合 里面是设备号和每日的日期 代码如下&#xff1a; static void Main(string[] args){string equipmentCodePar "";DateTime time DateTime.Now; // 获取当前时间DateTime startDate time.AddDays(1 - time.Day);//获取当前月第一…...

antdesign前端一直加载不出来

antdesign前端一直加载不出来 报错&#xff1a;Module “./querystring” does not exist in container. while loading “./querystring” from webpack/container/reference/mf at mf-va_remoteEntry.js:751:11 解决方案&#xff1a;Error: Module “xxx“ does not exist …...

排序算法介绍(一)插入排序

0. 简介 插入排序&#xff08;Insertion Sort&#xff09; 是一种简单直观的排序算法&#xff0c;它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。插入排序在实现上&#xff0c;通常…...

2023新优化应用:RIME-CNN-LSTM-Attention超前24步多变量回归预测算法

程序平台&#xff1a;适用于MATLAB 2023版及以上版本。 霜冰优化算法是2023年发表于SCI、中科院二区Top期刊《Neurocomputing》上的新优化算法&#xff0c;现如今还未有RIME优化算法应用文献哦。RIME主要对霜冰的形成过程进行模拟&#xff0c;将其巧妙地应用于算法搜索领域。 …...

RNN:文本生成

文章目录 一、完整代码二、过程实现2.1 导包2.2 数据准备2.3 字符分词2.4 构建数据集2.5 定义模型2.6 模型训练2.7 模型推理 三、整体总结 采用RNN和unicode分词进行文本生成 一、完整代码 这里我们使用tensorflow实现&#xff0c;代码如下&#xff1a; # 完整代码在这里 imp…...

Rust UI开发(五):iced中如何进行页面布局(pick_list的使用)?(串口调试助手)

注&#xff1a;此文适合于对rust有一些了解的朋友 iced是一个跨平台的GUI库&#xff0c;用于为rust语言程序构建UI界面。 这是一个系列博文&#xff0c;本文是第五篇&#xff0c;前四篇链接&#xff1a; 1、Rust UI开发&#xff08;一&#xff09;&#xff1a;使用iced构建UI时…...

Linux学习笔记2

web服务器部署&#xff1a; 1.装包&#xff1a; [rootlocalhost ~]# yum -y install httpd 2.配置一个首页&#xff1a; [rootlocalhost ~]# echo i love yy > /var/www/html/index.html 启动服务&#xff1a;[rootlocalhost ~]# systemctl start httpd Ctrl W以空格为界…...

数据结构算法-插入排序算法

引言 玩纸牌 的时候。往往 需要将牌从乱序排列变成有序排列 这就是插入排序 插入排序算法思想 先看图 首先第一个元素 我默认已有序 那我们从第二个元素开始&#xff0c;依次插入到前面已有序的部分中。具体来说&#xff0c;我们将第二个元素与第一个元素比较&#xff0c;…...