C++模板类带id模板参数的成员函数HLS编译匹配失败问题求解
错误原因
C++模板参数必须是编译期可确定的常量,你代码里普通for循环的i是运行期可变的变量,无法作为模板实参传入consume_fb_events的id参数,因此编译器抛出匹配失败的错误。
解决方案
以下方案均适配HLS硬件综合要求,无额外运行期开销:
方案1:使用std::integer_sequence做编译期循环展开(支持C++11及以上版本)
这种写法简洁,Vitis HLS、Vivado HLS 2019.1及以上版本均兼容:
#include <utility> #define sth 8 // 编译期展开调用的辅助函数 template <typename CoreType, std::size_t... I> void call_consume_fb(CoreType core[], decltype(buffer_layer1_1) buf, weight w1[], std::index_sequence<I...>) { // C++11版本用下面两行实现展开 int dummy[] = { (core[I].template consume_fb_events<I>(buf, w1[I]), 0)... }; (void)dummy; // 消除未使用变量警告 // 如果支持C++17可以直接用折叠表达式替换上面两行 // (core[I].template consume_fb_events<I>(buf, w1[I]), ...); } // 原for循环处替换为以下调用 call_consume_fb(core_1, buffer_layer1_1, w1, std::make_index_sequence<sth>{});
方案2:模板递归展开(兼容更旧的编译器版本)
如果不支持std::integer_sequence,可以手动实现递归模板展开:
#define sth 8 template <int idx, typename CoreType> void call_consume(CoreType core[], decltype(buffer_layer1_1) buf, weight w1[]) { core[idx].template consume_fb_events<idx>(buf, w1[idx]); // C++17用编译期if终止递归,C++11可以写特化版本的终止函数 if constexpr (idx + 1 < sth) { call_consume<idx + 1>(core, buf, w1); } } // 原for循环处替换为以下调用 call_consume<0>(core_1, buffer_layer1_1, w1);
关键注意项
调用依赖模板参数的成员模板函数时,必须加template关键字修饰consume_fb_events,否则编译器会把<解析为小于号,抛出语法错误。
内容的提问来源于stack exchange,提问作者Sherif Badawy
相关产品推荐
相关产品推荐

