SFINAE几种实现方式
一、通过函数返回值实现
template<class T>
typename std::enable_if<std::is_trivially_default_constructible<T>::value>::type
construct(T*)
{
std::cout << "default constructing trivially default constructible T\n";
}
template<class T, class... Args>
std::enable_if_t<std::is_constructible<T, Args&&...>::value> // Using helper type
construct(T* p, Args&&... args)
{
std::cout << "constructing T with operation\n";
::new(detail::voidify(p)) T(static_cast<Args&&>(args)...);
}
template<class T>
auto len (T const& t) -> decltype( (void)(t.size()), T::size_type() ) {
return t.size();
}
二、通过函数参数实现
template<class T>
void destroy(
T*,
typename std::enable_if<
std::is_trivially_destructible<T>::value
>::type* = 0
){
std::cout << "destroying trivially destructible T\n";
}
三、通过模板非类型参数实现
template<class T,
typename std::enable_if<
!std::is_trivially_destructible<T>{} &&
(std::is_class<T>{} || std::is_union<T>{}),
bool>::type = true>
void destroy(T* t)
{
std::cout << "destroying non-trivially destructible T\n";
t->~T();
}
四、通过模板类型参数实现
template<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t) // note: function signature is unmodified
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]);
}
}
当有多个重载时,不推荐使用该方式,会在C++语义上出现冲突,宜使用方法三。
五、通过模板偏特化实现
template <typename T, typename = void>
struct iterator_trait
: std::iterator_traits<T> {}; template <typename T>
struct iterator_trait<T, std::void_t<typename T::container_type>>
: std::iterator_traits<typename T::container_type::iterator> {};
六、通过c++20的concept实现
template<typename STR>
requires std::is_convertible_v<STR,std::string>
Person(STR&& n) : name(std::forward<STR>(n)) {
...
}
template<typename T>
concept ConvertibleToString = std::is_convertible_v<T,std::string>; ...
template<typename STR>
requires ConvertibleToString<STR>
Person(STR&& n) : name(std::forward<STR>(n)) {
...
}
template<ConvertibleToString STR>
Person(STR&& n) : name(std::forward<STR>(n)) {
...
}
SFINAE几种实现方式的更多相关文章
- Web APi之认证(Authentication)两种实现方式【二】(十三)
前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...
- CSS垂直居中的11种实现方式
今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...
- Android中BroadcastReceiver的两种注册方式(静态和动态)详解
今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...
- Android中Fragment与Activity之间的交互(两种实现方式)
(未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...
- Android开发之基本控件和详解四种布局方式
Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...
- 通过三个DEMO学会SignalR的三种实现方式
一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...
- Hive metastore三种配置方式
http://blog.csdn.net/reesun/article/details/8556078 Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储.远端存储比较适 ...
- Hive的三种安装方式(内嵌模式,本地模式远程模式)
一.安装模式介绍: Hive官网上介绍了Hive的3种安装方式,分别对应不同的应用场景. 1.内嵌模式(元数据保村在内嵌的derby种,允许一个会话链接,尝试多个会话链接时会报错) ...
- HashMap两种遍历方式的深入研究
转自:http://swiftlet.net/archives/1259 HashMap的遍历有两种方式,如下所示:第一种利用entrySet的方式: 1 2 3 4 5 6 7 Map map ...
- JavaScript 函数的两种声明方式
1.函数声明的方式 JavaScript声明函数有两种选择:函数声明法,表达式定义法. 函数声明法 function sum (num1 ,num2){ return num1+num2 } 表达式定 ...
随机推荐
- 《用Python写网络爬虫》pdf高清版免费下载
<用Python写网络爬虫>pdf高清版免费下载地址: 提取码:clba 内容简介 · · · · · · 作为一种便捷地收集网上信息并从中抽取出可用信息的方式,网络爬虫技术变得越来越有 ...
- HTTP知识点
HTTP 请求/响应的步骤:(工作原理) 客户端连接到 Web 服务器 一个 HTTP 客户端,通常是浏览器,与 Web 服务器的 HTTP 端口(默认为 80)建立一个 TCP 套接字连接.例如,h ...
- js实现大转盘抽奖(vue举例)
在开发项目得时候遇到这样一个需求,在移动端项目有个支付抽奖页面,大概效果图如下: 简单介绍一下需求,点击抽奖按钮转盘转动,转盘里边黄色块块是个整张背景图,里边的商品是从接口获取得,包括奖品名称和图片, ...
- Java面向对象之抽象类abstract
抽象类abstract 普通类 普通类可以直接产生实例化对象,并且在普通类之中可以包含有构造方法,普通方法.static 方法.常量.变量的内容. 所有的普通方法都会有一个"{}" ...
- A调用B方法,@Transactional事务问题
总结:方法A调用方法B:1.如果只有A加@Transactional注解:则AB在同一事务中,任意异常都回滚:2.如果只有B加@Transactional注解:AB方法为同一类,事务失效任意异常都不回 ...
- appcrawler(2.1.3)采坑
转发:https://www.jianshu.com/p/d97290136bad 遇到的坑: 问题1: Exception in thread "main" org.openqa ...
- C3861: “CoInitialize”“CoUninitialize”: 找不到标识符
error C3861: "CoInitialize": 找不到标识符error C3861: "CoUninitialize": 找不到标识符 包含头文件和链 ...
- 通过ESP8266WiFi模块调用“心知天气”接口 获取天气信息
在分析代码之前,首先介绍 ArduinoJson 库的安装及"心知天气"的ID申请 一.安装 ArduinoJson 库 进入 Arduino 开发环境后,选择菜单栏-->工 ...
- CompletableFuture使用方法的详细说明
异步执行一个任务时,我们一般是使用自定义的线程池Executor去创建执行的.如果不需要有返回值, 任务实现Runnable接口:如果需要有返回值,任务实现Callable接口,调用Executor的 ...
- 使用 PSAPI 库枚举进程 EnumProcesses()函数
使用 PSAPI 库枚举进程 在 Windows NT 中,创建进程列表使用 PSAPI 函数,这些函数在 PSAPI.DLL 中.这个文件是随 Platform SDK 一起分发的: 使用这个库所需 ...