热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

C++模板元编程中的一些函数特性【完善中】

1.std::enable_ifstd::enable_if顾名思义,满足条件时类型有效。它只有在第一个模板参数为true的时候才会定义type。1.1源码实现:template

1.std::enable_if

std::enable_if 顾名思义,满足条件时类型有效。它只有在第一个模板参数为true的时候才会定义type。


1.1 源码实现:

template
struct enable_if {};

template
struct enable_if { typedef T type; };

1.2 使用示例:


1.2.1 基本用法: 

typename std::enable_if<{BOOL 表达式}>::type


1.2.2 通过返回值使用:

对于模板函数,有时希望根据不同的模板参数返回不同类型的值,进而给函数模板也赋予类型模板特化的性质。典型的例子可以参看 tuple 的获取第 k 个元素的 get 函数。以下为另一种简单示例

template
typename std::enable_if::value>::type
construct(T* t,Args&&... args)
{
std::cout <<"constructing trivially constructible T\n";
}

T和参数包...Args中的对象都是std::is_trivially_constructible时(即:可默认构造),std::enable_if的结果为void


1.2.3 通过模板函数参数使用

有时定义的模板函数,只希望特定的类型可以调用,此时在函数参数中使用enable_if

template
void destroy(
T* t, //第一个参数
typename std::enable_if std::is_trivially_destructible::value
>::type* = 0)
{
std::cout <<"destroying trivially destructible T\n";
}

T的类型满足is_trivially_destructible的条件(即:可平凡析构),第二个参数的类型为void *并取默认值void* = 0

需要注意的是,这样操作后,函数的签名实际上变为了void destroy(T*, void*)。 这种操作的实质,是为了确保第一个参数是特定的类型(或满足特定的条件)。

常见错误
一个常见的错误是:声明了两个函数模板,它们只有默认模板实参不同

这是非法的,因为默认的模板实参不是函数模板签名的一部分,并且声明两个具有相同签名的不同函数模板是非法的。

/*** 错误典型 ***/
 
struct T {
    enum { int_t,float_t } m_type;
    template               typename = std::enable_if_t::value>
    >
    T(Integer) : m_type(int_t) {} //T(U)
 
    template               typename = std::enable_if_t::value>
    >
    T(Floating) : m_type(float_t) {} // 错误:无法重载,因为其签名也是 T(U)
};
 
/* 正确示例 */
 
struct T {
    enum { int_t,float_t } m_type;
    template               std::enable_if_t::value, int> = 0
    >
    T(Integer) : m_type(int_t) {} //仅当Integer为int时,签名为 T(int),否则SFINAE
 
    template               std::enable_if_t::value, int> = 0
    >
    T(Floating) : m_type(float_t) {} // 仅当Floating为浮点类型时,签名为,例如 T(double) 否则SFINAE
};

 

参考原文链接:https://blog.csdn.net/wbvalid/article/details/119352979



推荐阅读
  • 深入理解Redis集群机制
    本文旨在深入探讨Redis集群的工作原理,包括其架构设计、数据分布策略、节点通信及故障恢复机制等方面的内容。 ... [详细]
  • 本文作者分享了在某大型IToIP解决方案提供商参与多个项目开发的经验与感悟,特别是在软件工程方法论上的思考,提出了对现有开发模式的见解及改进建议。 ... [详细]
  • 实践指南:利用Jenkins与JMeter实现自动化测试报告通知
    本文详细介绍了如何结合Jenkins和JMeter工具,通过自定义脚本向用户发送测试报告的通知。这不仅提高了开发团队的工作效率,也确保了信息的及时传递。 ... [详细]
  • 2023年PHP处理请求超时的全面指南
    本文详细介绍了在PHP中处理请求超时的各种方法,包括设置脚本执行时间、处理file_get_contents函数超时以及优化AJAX请求等,适合开发者参考学习。 ... [详细]
  • ANSI最全介绍linux终端字体改变颜色等ANSI转义序列维基百科,自由的百科全书由于国内不能访问wiki而且国内关于ANSI的介绍都是简短的不能达到,不够完整所以转wiki到此 ... [详细]
  • 本文详细介绍了如何使用Python来合并两个已经按升序排列的链表,同时保持合并后链表的有序性。 ... [详细]
  • 本文提供了详细的指导,帮助开发者了解如何使用PHP插件进行网站内容的翻译,特别是针对WordPress插件和主题的汉化及多语言支持。 ... [详细]
  • 深入解析线程池的工作原理与实际应用
    本文详细探讨了线程池的核心概念、工作原理及其在实际开发中的应用,包括不同类型的线程池创建方式及其适用场景。 ... [详细]
  • Cortex-M3处理器核心解析
    本文详细介绍了Cortex-M3处理器的常见术语及其核心特点,包括其架构、寄存器组、操作模式、中断处理机制、存储器映射、总线接口和存储器保护单元(MPU)。此外,还探讨了Cortex-M3在性能和中断处理方面的优势。 ... [详细]
  • 浏览器、中间件与服务器的交互机制
    本文详细探讨了浏览器、中间件和服务器之间的交互过程,特别是HTTP请求的完整流程,包括DNS解析、TCP连接建立及数据传输等关键步骤。 ... [详细]
  • 本文详细探讨了Java中多线程环境下的异步处理机制,特别是Future和CompletableFuture的使用方法,通过实例代码帮助读者更好地理解和应用这些技术。 ... [详细]
  • Linux系统中高效解决高Buff/Cache占用问题
    本文详细探讨了在Linux系统中遇到的高Buff/Cache占用问题及其解决方案,提供了手动清除与定时任务自动化处理的方法。 ... [详细]
  • 查找数组中的重复元素
    问题描述:给定一个长度为n的数组,其中所有元素值位于0至n-1之间。数组中存在一些重复的数字,但具体哪些数字重复以及重复了多少次未知。本文章将探讨如何高效地找到数组中的任一重复数字。 ... [详细]
  • 本文详细探讨Java中Scanner类的两个重要方法——nextInt()和nextDouble(),并通过实例代码演示如何使用这些方法来处理用户输入。 ... [详细]
  • django项目中使用手机号登录
    本文使用聚合数据的短信接口,需要先获取到申请接口的appkey和模板id项目目录下创建ubtils文件夹,定义返回随机验证码和调取短信接口的函数function.py文件se ... [详细]
author-avatar
时光-Goslow
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有