使用boost mp11有效地打开运行时值完成处理功能时中断

如何解决使用boost mp11有效地打开运行时值完成处理功能时中断

我有以下code,其中我在运行时值上实现分派,以某种方式解释数据(在此玩具示例中,数据可以是uint8_t或short)。

代码似乎可以工作,但是我想知道是否可以以某种方式对代码进行微优化,以便在命中(处理函数匹配)时停止处理(当前,即使元组的第一个元素是“处理程序”,整个元组也是如此)。在运行时进行迭代)。

#include <boost/mp11/tuple.hpp>
#include <iostream>

uint8_t data[4] = {0,1,100,2};

template<int runtimeId,typename T>
struct kindToType{
    static constexpr int id =  runtimeId;
    using type = T;
};

 const auto print  =[]<typename T> (const T* data){
    if constexpr(std::is_same_v<short,std::remove_cvref_t<T>>){
        const short* values = (const short*)data;
        std::cout << values[0] << "  " << values[1] << std::endl;
    } else if constexpr(std::is_same_v<uint8_t,std::remove_cvref_t<T>>){
        const uint8_t* values = (const uint8_t*)data;
    std::cout << (int)values[0] << "  " << (int)values[1]<< "  " << (int)values[2] << "  " << (int)values[3] << std::endl;;
    }
};

static constexpr std::tuple<kindToType<10,uint8_t>,kindToType<11,short>> mappings{};

void dispatch(int kind){
    boost::mp11::tuple_for_each(mappings,[kind]<typename Mapping>(const Mapping&) {
    if (Mapping::id == kind)
    {
        print((typename Mapping::type*)data);
    }
    });
}
int main()
{
    // no guarantee that kind is index like(e.g. for two values
    // it can have values 47 and 1701)
    dispatch(10);
    dispatch(11);
}

注意:

  • 我不能/不想使用std :: variant。
  • 我不想使用std :: map或std :: unordered map(其中值为std::function
  • 我知道这是过早的优化(假设处理程序完成大量工作,即使进行10次整数比较也很便宜)。
  • 我的处理程序是唯一的,即它是std :: map之类的东西,而不是std :: multimap之类的东西,所以break;很好。
  • 用于运行时值的id类型不能保证其值在[0,n-1]中。
  • 只要在至少1个编译器中实现,我对C ++ 20解决方案就可以了。

解决方法

这的运行时性能在很大程度上取决于元组的大小。您可以创建自己的for_each_tuple实现,以便在执行函数时尽早实现:

template<typename FuncTuple,typename Selector>
void tuple_for_each(FuncTuple const& funcTuple,Selector selector) 
{
    std::apply([selector](auto const& ...funcs)
    {
        (void)(selector(funcs) || ...);
    },funcTuple);
}

您的调度将如下所示:

void dispatch(int kind)
{
    tuple_for_each(mappings,[kind]<typename Mapping>(const Mapping&) 
    {
        std::cout << "loop,";
        if (Mapping::id == kind)
        {
            print((typename Mapping::type*)data);
            return true;
        }
        return false;
    });
}

如果您摆脱了lambda中的模板,而使用auto,则此代码将在C ++ 17中编译。我们利用操作员短路来发挥我们的优势,因此编译器将为我们提供早期解决方案。 Here是完整代码。

另外,请注意,强制转换(const short*)data是UB。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-