C++ 元编程 学习二
简介
C++ 元编程 学习之二
参考资料
C++ 模板元编程实战
code
#include <iostream>
// 编译器分支与多种返回类型 写法1
template <bool Check, std::enable_if_t<Check> * = nullptr>
auto fun(){
return (int) 0;
}
template <bool Check, std::enable_if_t<!Check> * = nullptr>
auto fun() {
return (double) 1;
}
template<bool Check>
auto wrap2() {
return fun<Check>();
}
// 编译期分支与多种返回类型 C++17
template <bool Check>
auto fun_(){
if constexpr (Check) { // 编译期接收值,然后构建运行期的函数
return (int) 0;
}else {
return (double) 1;
}
}
// 循环代码实现 使用递归实现
template <size_t Input>
constexpr size_t OnesCount = (Input % 2) + OnesCount<(Input / 2)>;
// 终止递归
template<> constexpr size_t OnesCount<0> = 0;
// 循环代码实现 对于数组求和
template <size_t...Inputs>
constexpr size_t Accumulate = 0;
template<size_t CurInput, size_t ...Inputs>
constexpr size_t Accumulate <CurInput, Inputs...> = CurInput + Accumulate<Inputs...>;
// C++ 17 实现技术
template<size_t... values>
constexpr size_t fun_1(){
return (0 + ... + values);
}
// 容易实例爆炸
// template <size_t A>
// struct Wrap_{
// template <size_t ID, typename TDummy = void>
// struct imp {
// constexpr static size_t value = ID + imp<ID - 1>::value;
// };
// template <typename TDummy>
// struct imp<0, TDummy> {
// constexpr static size_t value = 0;
// };
// template <size_t ID>
// constexpr static size_t value = imp<A + ID>::value;
// };
// 不容易实例爆炸的样例 公用了 imp的实现
template <size_t ID>
struct imp {
constexpr static size_t value = ID + imp<ID - 1>::value;
};
template<>
struct imp<0> {
constexpr static size_t value = 0;
};
template <size_t A>
struct Wrap_{
template <size_t ID>
constexpr static size_t value = imp<A + ID>::value;
};
// 短路逻辑未实现的版本 判断是否全是素数
/*
template <size_t N>
constexpr bool is_odd = ((N % 2) == 1);
template <size_t N>
struct AllOdd_ {
constexpr static bool is_cur_odd = is_odd<N>;
constexpr static bool is_pre_odd = AllOdd_<N - 1>::value;
constexpr static bool value = is_cur_odd && is_pre_odd;
};
template <>
struct AllOdd_<0> {
constexpr static bool value = is_odd<0>;
};
*/
template <size_t N>
constexpr bool is_odd = ((N % 2) == 1);
template <bool cur, typename TNext>
constexpr static bool AndValue = false;
template <typename TNext>
constexpr static bool AndValue<true, TNext> = TNext::value;
template<size_t N>
struct AllOdd_ {
constexpr static bool is_cur_odd = is_odd<N>;
constexpr static bool value = AndValue<is_cur_odd, AllOdd_<N - 1>>;
};
template <>
struct AllOdd_<0> {
constexpr static bool value = is_odd<0>;
};
// 构建虚函数 通过CRTP
template<typename D>
struct Base{
template <typename TI>
void Fun(const TI&input){
D* ptr = static_cast<D*>(this);
ptr->Imp(input);
}
};
struct Derive : public Base<Derive>{
template <typename TI>
void Imp(const TI& input){
std::cout << input << std::endl;
}
};
// 类的静态函数被声明为虚函数?QU:什么鬼
template <typename D>
struct Base1{
static void Fun(){
D::Imp();
}
};
struct Derive1: public Base1<Derive1>{
static void Imp(){
std::cout << "Implementation from derive class11" << std::endl;
}
};
#include "header1.hh"
using namespace std;
int main() {
cerr << wrap2<true>() << std::endl;
cerr << wrap2<false>() << std::endl;
std::cerr << fun_<true>() << std::endl;
constexpr size_t res = OnesCount<45>;
std::cerr << res << std::endl;
constexpr size_t res1 = Accumulate<1, 2, 3, 4, 5>;
std::cerr << res1 << std::endl;
constexpr size_t res2 = fun_1<1,2,3,4,5>();
std::cerr << res2 << std::endl;
std::cerr << Wrap_<3>::value<2> << std::endl;
std::cerr << Wrap_<10>::value<2> << std::endl;
Derive d;
d.Fun("Implementation from derive class");
Derive1::Fun();
}
C++ 元编程 学习二的更多相关文章
- 扩展C#与元编程(二)
如果你对Windows Workflow Foundation(WF)一无所知,当看到扩展C#与元编程(一)中由MW编译器生成的FirstLook.mw.cs时,也许这么在想:我KAO,这是C#版的汇 ...
- C++ 模板元编程 学习笔记
https://blog.csdn.net/K346K346/article/details/82748163 https://www.jianshu.com/p/b56d59f77d53 https ...
- Linux网络编程学习(二) ----- 进程控制(第三章)
1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...
- 网络编程学习二(IP与端口)
InetAddress类 封装计算机的ip地址,没有端口 // 使用getLocalHost方法创建InetAddress对象 InetAddress addr = InetAddress.getLo ...
- 流畅的python第十九章元编程学习记录
在 Python 中,数据的属性和处理数据的方法统称属性(attribute).其实,方法只是可调用的属性.除了这二者之外,我们还可以创建特性(property),在不改变类接口的前提下,使用存取方法 ...
- 扩展C#与元编程
扩展C#与元编程 https://www.cnblogs.com/knat/p/4580393.html https://www.cnblogs.com/knat/p/4584023.html 扩展C ...
- 多线程编程学习笔记——async和await(二)
接上文 多线程编程学习笔记——async和await(一) 三. 对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...
- 爬虫概念与编程学习之如何爬取视频网站页面(用HttpClient)(二)
先看,前一期博客,理清好思路. 爬虫概念与编程学习之如何爬取网页源代码(一) 不多说,直接上代码. 编写代码 运行 <!DOCTYPE html><html><head& ...
- Linux学习之socket编程(二)
Linux学习之socket编程(二) 1.C/S模型——UDP UDP处理模型 由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实 ...
- 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(中)
学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 四.创建一个Blazor应用程序 1. 第一种创 ...
随机推荐
- Python3_模块(一)
脚本是用 python解释器来编程,如果从 Python解释器退出再进入,那么你定义的所有的方法和变量就都消失了.为此 Python提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器 ...
- Python3处理文档_word文档实现自动化办公(一)
最近打算写一个自动化出报告的脚本 先从处理word文档开始 Python 操作 Word 最常见的依赖库是:python-docx 所以,在开始操作之前,我们需要在虚拟环境下安装这个依赖库 pip3 ...
- scrcpy - Android手机投屏操作神器
推荐一个Genymotion推出的投屏工具,跨平台,自定义码率,最重要的是开源,简直良心. Github:https://github.com/Genymobile/scrcpy 下载地址: http ...
- ESP32S3 OTA升级
ESP32S3 OTA升级 学习自b站视频[ESP-IDF-OTA远程升级简单介绍-宋工]https://www.bilibili.com/video/BV1X1zbYGEix?vd_source=a ...
- 制作带sshd功能的centos镜像
docker run -it --name node1 docker.io/centos bash 创建node1容器 docker exec -it node1 bash 进入node1 yum ...
- cf记录
cf2107D \(Question:\)给定一个节点为\(n(1 \leq n \leq 2e5)\)的树,定义三元组\((d,u,v)\)为从点\(u\)到点\(v\)的路径长度\(d\),每次选 ...
- Docker不装C盘
Docker默认安装在C盘,这未来随着docker使用必定会导致C盘空间吃紧.所以本文提前进行空间布局,将docker默认安装路径软链接到D盘.软链接D盘Docker默认安装路径为C:\Program ...
- QQ会员首页HTML+CSS
作为一个穷人,唯一一次逛这么久的会员首页还是因为要写最头大的web~苦涩 效果图 源码 <!DOCTYPE html> <html> <head> <meta ...
- cf 870div2 abcd题解
A题,先假设一个res从0开始,判断说谎人的个数用ans表示,如果res==ans则假设成立 #include<iostream> using namespace std; typedef ...
- odoo16里面的常用方法
一.全局搜索与显示 def name_get(self): res = [] for order in self: name = order.name if order.draw_number: na ...