C++11模板元编程-std::enable_if示例详解

2023-11-17

传送门 ==>> AutoSAR实战系列300讲「糖果Autosar」总目录

C++11中引入了std::enable_if函数,函数原型如下:

template< bool B, class T = void >
struct enable_if;

可能的函数实现:

template<bool B, class T = void>
struct enable_if {};
  
template<class T>
struct enable_if<true, T> { typedef T type; };

由上可知,只有当第一个模板参数为true时,enable_if会包含一个type=T的公有成员,否则没有该公有成员。

头文件:

#include <type_traits>

std::enable_if使用场景

1 限制模板函数的参数类型

在某些场景下,我们需要实现只有特定类型可以调用的模板函数。如下代码所示,通过对返回值使用std::enable_if和在模板参数中使用std::enable_if均实现了只允许整形参数调用函数的功能。

// enable_if example: two ways of using enable_if
#include <iostream>
#include <type_traits>
 
// 1. the return type (bool) is only valid if T is an integral type:
template <class T>
typename std::enable_if<std::is_integral<T>::value,bool>::type
 is_odd (T i) {return bool(i%2);}
 
// 2. the second template argument is only valid if T is an integral type:
template < class T,class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even (T i) {return !bool(i%2);}
 
int main() {
 
 short int i = 1;  // code does not compile if type of i is not integral
 
 std::cout << std::boolalpha;
 std::cout << "i is odd: " << is_odd(i) << std::endl;
 std::cout << "i is even: " << is_even(i) << std::endl;
 
 return 0;
}

当使用float类型参数调用函数时,程序会报错:

error: no matching function for call to ‘is_odd(float&)’

2 模板类型偏特化

在使用模板编程时,可以利用std::enable_if的特性根据模板参数的不同特性进行不同的类型选择。

如下所示,我们可以实现一个检测变量是否为智能指针的实现:

#include <iostream>
#include <type_traits>
#include <memory>
 
template <typename T>
struct is_smart_pointer_helper : public std::false_type {};
 
template <typename T>
struct is_smart_pointer_helper<std::shared_ptr<T> > : public std::true_type {};
 
template <typename T>
struct is_smart_pointer_helper<std::unique_ptr<T> > : public std::true_type {};
 
template <typename T>
struct is_smart_pointer_helper<std::weak_ptr<T> > : public std::true_type {};
 
template <typename T>
struct is_smart_pointer 
: public is_smart_pointer_helper<typename std::remove_cv<T>::type> 
{
};
 
template <typename T>
typename std::enable_if<is_smart_pointer<T>::value,void>::type 
check_smart_pointer(const T& t)
{
  std::cout << "is smart pointer" << std::endl;
}
 
template <typename T>
typename std::enable_if<!is_smart_pointer<T>::value,void>::type 
check_smart_pointer(const T& t)
{
  std::cout << "not smart pointer" << std::endl;
}
 
int main()
{
  int* p(new int(2));
  std::shared_ptr<int> pp(new int(2));
  std::unique_ptr<int> upp(new int(4));
 
  check_smart_pointer(p);
  check_smart_pointer(pp);
  check_smart_pointer(upp);
   
  return 0;
}

程序输出:

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

C++11模板元编程-std::enable_if示例详解 的相关文章

  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 计算 XML 中特定 XML 节点的数量

    请参阅此 XML
  • GetType() 在 Type 实例上返回什么?

    我在一些调试过程中遇到了这段代码 private bool HasBaseType Type type out Type baseType Type originalType type GetType baseType GetBaseTyp
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 为什么可以通过ref参数修改readonly字段?

    考虑 class Foo private readonly string value public Foo Bar ref value private void Bar ref string value value hello world
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • 检测到严重错误 c0000374 - C++ dll 将已分配内存的指针返回到 C#

    我有一个 c dll 它为我的主 c 应用程序提供一些功能 在这里 我尝试读取一个文件 将其加载到内存 然后返回一些信息 例如加载数据的指针和内存块的计数到 c Dll 成功将文件读取到内存 但在返回主应用程序时 程序由于堆损坏而崩溃 检测
  • C++ new * char 不为空

    我有一个问题 我在 ASIO 中开发服务器 数据包采用尖头字符 当我创建新字符时 例如char buffer new char 128 我必须手动将其清理为空 By for int i 0 i lt 128 i buffer i 0x00
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s
  • 如何在richtextbox中使用多颜色[重复]

    这个问题在这里已经有答案了 我使用 C windows 窗体 并且有 richtextbox 我想将一些文本设置为红色 一些设置为绿色 一些设置为黑色 怎么办呢 附图片 System Windows Forms RichTextBox有一个
  • 是否可以在不连接数据库的情况下检索 MetadataWorkspace?

    我正在编写一个需要遍历实体框架的测试库MetadataWorkspace对于给定的DbContext类型 但是 由于这是一个测试库 我宁愿不连接到数据库 它引入了测试环境中可能无法使用的依赖项 当我尝试获取参考时MetadataWorksp
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐

  • 应用程序,操作系统,驱动程序的关系

    硬件和软件 计算机资源分为硬件资源和软件资源 硬件资源包括cpu 内存 显卡 网卡 声卡 硬盘等等 软件资源包括各种程序 每个硬件完成特定的功能 比如显卡完成在显示设备上显示图形 声卡实现声音的处理 再比如 你用qq发送一段文字给一个同学
  • VUE3使用JSON编辑器

    1 先看看效果图 可以自行选择展示效果 2 这是我在vue3项目中使用的JSON编辑器 首先引入第三方插件 npm install json editor vue3 yarn add json editor vue3 3 引入到项目中 导入
  • 强化学习实践二 :理解gym的建模思想

    David Silver的强化学习公开课有几个特点 个人感觉首要的一个特点是偏重于讲解理论 而且有时候为了讲清楚一个理论的来龙去脉 也顺带讲了很多不常用的理论 还有一个特点是小例子很多 这些例子有时候不仅是为了讲清楚一个复杂的算法 而且通过
  • [Redis] Redis 安装部署

    Redis Redis 安装部署 简介 Redis是一个开源的使用ANSI C语言编写 遵守BSD协议 支持网络 可基于内存亦可持久化的日志型 Key Value 数据库 并提供多种语言的API 它通常被称为数据结构服务器 因为值 valu
  • 查看Postgresql的连接状况

    今天遇到一个问题 就是pg一直报错 说有太多的客户端连接到数据库上面 但现在不知道是什么程序连接 pg默认的max connection是100 我并没有修改过 以为平时公司内部用 应该够了 但现在貌似这100个连接都被消耗掉 在网上goo
  • 【CSS】如何用css做一个爱心

    摘要 HTML的标签都比较简单 入门非常的迅速 但是CSS是一个需要我们深度挖掘的东西 里面的很多样式属性掌握几个常用的便可以实现很好看的效果 下面我便教大家如何用CSS做一个爱心 前期预备知识 明白正方形的画法 明白圆形的画法 明白什么是
  • Android下基于Http协议的网络摄像机开发

    这段时间在做Android平台下的网络摄像机的兼容 摄像机的通讯采用Http1 1协议 现将遇到的问题简单总结一下 1 Http协议中需要用到身份认证部分 不同厂家的摄像机所采取的方案可能有所不同 但是大体无外乎都是将摄像机的用户名和密码简
  • 江科大自化协STM32学习笔记(部分C语言知识、STM32简介和GPIO口的使用)

    本篇文章是根据B站UP主江科大自化协的教学视频STM32入门教程 2023持续更新中 在了解 学习与实操后整理的学习笔记 内容部分来自UP主的课程资料 并包含了一些个人的理解 如有谬误欢迎指正 详细知识点可以观看UP主的视频进行了解 希望大
  • php如何读取解析eml文件以及生成网页的示例分享

    这篇文章主要介绍了PHP读取 解析eml文件及生成网页的方法 结合实例形式分析了PHP操作eml文件的读取 解析 转换等相关实现技巧与注意事项 并附带demo源码供读者下载参考 需要的朋友可以参考下 本文实例讲述了PHP读取 解析eml文件
  • Linux及Windows下编译exosip和osip2源码

    eXosip库及编译流程简介 1 eXosip库的简介 1 1 osip简介 osip2是一个开放源代码的sip协议栈 是开源代码中不多使用C语言写的协议栈之一 它具有短小简洁的特点 专注于sip底层解析使得它的效率比较高 但缺点也很明显
  • 前端通过FormData上传文件到服务器端

    前端代码 html
  • Win 11 打开未知文件/打开方式 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联。

    问题 鼠标右键选中文件 打开方式 或者选择其他应用 弹窗提示 该文件没有与之关联的应用来执行该操作 请安装应用 若已经安装应用 请在 默认应用设置 页面中创建关联 打开注册表 查看是否存在以下路径 HKEY CLASSES ROOT Unk
  • Visual Studio Code如何打开多个tab标签

    原创 Visual Studio Code如何打开多个tab标签 SweetTool的专栏 CSDN博客 在打开文件夹预览的模式下VS Code默认单击打开文件时仅保存一个tab 例如当前window打开一个tabA 然后点击另外一个文件B
  • 带你了解ES6 Module

    1 commonJS 在说 es6 模块以前 我们先来看一下后端普遍使用的打包方式 commonJS的一些特性 同步加载 也就是串行执行 后面的任务要等到前面任务执行完才能继续执行 语法 commonJS中使用 require 引入 mod
  • [Paper-CV] ECCV 2012 papers 1

    http applesun0757 blog 163 com blog static 18737419220126702145274 Paper CV ECCV 2012 papers 1 2012 07 07 00 21 45 分类 Pa
  • linux中替换命令详解,linux中tr命令详解 (替换,删除d,缩减s)

    tr用来从标准输入中通过替换或删除操作进行字符转换 tr主要用于删除文件中控制字符或进行字符转换 特别要注意一点 tr 只能进行字符的替换 缩减和删除 不能用来替换字符串 最常用选项的tr命令格式为 tr c d s string1 to
  • C# 网络编程之Tcp实现客户端和服务器聊天

    最近使用Socket网络套接字编程中 在同步与异步通讯中客户端与服务器总是无法响应 但在学习Tcp协议编程中完成了通讯聊天功能 下面简单讲讲我最近学到的及Tcp聊天的源代码及详细注释 Tcp协议是一个传输层的协议 在Tcp协议编程中它通常使
  • OpenGL超级宝典 纹理(一)

    文章目录 纹理 创建并且初始化纹理 更新纹理数据 从着色器中读取数据 采样器类型 控制纹理数据的读取方式 创建采样器对象和绑定到纹理单元 纹理过滤 设置过滤器 加载纹理 完整代码展示 shader vertex shader fragmen
  • mysql 授权管理和设置

    1 给指定数据库增加所有权限 所有库即 GRANT ALL PRIVILEGES ON TO 用户名 IDENTIFIED BY 密码 WITH GRANT OPTION 设置完之后更新权限表 FLUSH PRIVILEGES 2 给用户增
  • C++11模板元编程-std::enable_if示例详解

    文章目录 1 限制模板函数的参数类型 2 模板类型偏特化 传送门 gt gt AutoSAR实战系列300讲 糖果Autosar 总目录 C 11中引入了std enable if函数 函数原型如下 template lt bool B c