首页 > 其他分享 >meta program - 实例化

meta program - 实例化

时间:2023-07-16 16:01:13浏览次数:51  
标签:struct 实例 pow value program meta template exp

template <typename T, T b, uint32_t e>
struct pow : std::integral_constant<decltype(b * 1), b * pow<T, b, e - 1>::value> {};

template <typename T, T b>
struct pow<T, b, 0> : std::integral_constant<decltype(b * 1), T(1)> {};

template <uint32_t e>
using pow_two_with_exp = pow<uint64_t, 2, e>;

template<size_t N, size_t exp>
struct SizeOfBits {
    static  uint32_t value = (N / pow_two_with_exp<exp>::value) == 0 ? exp:SizeOfBits<N,exp+1>::value;
};

这个meta program用来计算N占用多少个bit表示。
乍看起来没有什么问题,因为对于<N,exp>,计算value时:如果\(2^{exp}>N\)时, 可以得知使用exp位可以表示N;否则测试<N,exp+1>
不过这段代码实际的问题是: 1.条件运算符会实例化所有的分支; 2.使用了::运算符访问类中的成员会促使类的所有成员被实例化。
可以看到这段代码会导致编译期模板递归超过限制


所以,可以将模板改写成这样:

template<size_t N, size_t exp=0>
struct SizeOfBits {
    static constexpr uint32_t value = IfThenElse<exp,SizeOfBits<N,exp+1>,(N / pow_two_with_exp<exp>::value) == 0>::value;
};


template <size_t A, typename B>
struct IfThenElse<A,B,true>{
    static constexpr size_t value = A;
};
template <size_t A, typename B>
struct IfThenElse<A,B,false>{
    static constexpr decltype(B::value) value = B::value;
};

这段代码的主要修改是使用了IfThenElse
这可以使在计算规模为<N,exp>的SizeOfBits::value时,只实例化一个分支(特化true或者特化false,模板的on demand实例化,见complete guide 1st edition chapter10)

此外,complete guide中还提及了一种归纳变量的方法,以使meta programm更像从递归改为迭代的设计:

标签:struct,实例,pow,value,program,meta,template,exp
From: https://www.cnblogs.com/ijpq/p/17557986.html

相关文章

  • *** These critical programs are missing or too old: compiler
     001、问题 ***Thesecriticalprogramsaremissingortooold:compiler 002、查看c编译器版本[root@PC1build]#gcc--versiongcc(GCC)4.8.520150623(RedHat4.8.5-44)Copyright(C)2015FreeSoftwareFoundation,Inc.Thisisfreesoftware;seethe......
  • *** These critical programs are missing or too old: make compiler
     001、问题***Thesecriticalprogramsaremissingortooold:makecompiler 002、查看当前的make版本[root@PC1build]#make--version 003、make官网:http://ftp.gnu.org/pub/gnu/make/下载最新的make。 004、wgethttp://ftp.gnu.org/pub/gnu/make/ma......
  • freee Programming Contest 2023(AtCoder Beginner Contest 310)题解
    点我看题A-OrderSomethingElse直接比较\(P\)和\(Q+min(D_i)\),输出较小值即可。点击查看代码#include<bits/stdc++.h>#definerep(i,n)for(inti=0;i<n;++i)#definerepn(i,n)for(inti=1;i<=n;++i)#defineLLlonglong#definefifirst#definesesecond#defi......
  • Template Metaprogramming
    #include<bits/stdc++.h>usingnamespacestd;template<typename...>structTypeList;template<typenameHead,typename...Tails>structTypeList<Head,Tails...>{usinghead=Head;usingtails=TypeList<Tails...>;};template&......
  • 【Azure K8S】记录AKS VMSS实例日志收集方式
    问题描述如何从AKS的VMSS集群中收集实例日志? 参考步骤第一步:登陆VMSS实例参考官网步骤:使用SSH连接到AzureKubernetes服务(AKS)群集节点以进行维护或故障排除: https://docs.azure.cn/zh-cn/aks/ssh#configure-virtual-machine-scale-set-based-aks-clusters-for-ssh......
  • <meta-data/> 标签的作用
    标签应用示例:<activityandroid:name="Settings$SimSettingsActivity"android:label="@string/sim_settings_title"android:icon="@drawable/ic_settings_sim"android:exported="false"a......
  • shell多线程/实例
    1.Shell实现多进程  使用&和wait配合实现shell多进程并行  参考连接:https://blog.csdn.net/yuefei169/article/details/83340480  (1)改串行执行为并行执行方式:将前台执行命令放在后台执行(串行命令后加&符号).(生产少使用该方式)  (2)使用元祖模拟队列来控制进程数......
  • centos7.4 yum 安装包的实现多实例
    1yuminstallmariadb-server2mkdir/mysqldb/{3306,3307,3308}/{etc,socket,pid,log,data}-pvchown-Rmysql.mysql/mysqldb/3mysql_install_db--datadir=/mysqldb/3306/data--user=mysqlmysql_install_db--datadir=/mysqldb/3307/data--user=mysqlmysql_inst......
  • docker 检查SQL Server实例的TCP/IP协议是否已启用
    检查SQLServer实例的TCP/IP协议是否已启用作为一名经验丰富的开发者,我将帮助你学习如何检查SQLServer实例的TCP/IP协议是否已启用。以下是整个流程以及每一步需要做的事情。流程步骤描述1连接到SQLServer实例2查询是否已启用TCP/IP协议3根据查询结果判断TC......
  • Qt信号槽信号函数重载问题 error: C2664: “QMetaObject::Connection const”
    //connect(spinFontSize,&QSpinBox::valueChanged,this,&MainWindow::spinFontSize_valueChanged);//由于信号函数存在重载,发送者找不到正确信号函数。//改用A.Qt4带形参方式//connect(spinFontSize,SIGNAL(valueChanged(int)),this,SLOT(spinFontSize_valueChang......