可变参数模板参数传递至另一模板报错,求修复方案
问题:编译时模板循环调用报错修复
我用C++模板元编程实现了static_for编译时循环和接受可变参数的loop_types结构体,但调用call函数时始终报错。将Args...替换为int,char,bool这类具体类型时代码可正常运行,需要修复该问题,预期程序能打印call函数每个参数的类型名称。
原代码
//Template specialization for getting an index of variadic template template <unsigned long long index, typename... P> struct variadic_type_template_index; template <typename T,typename... P> struct variadic_type_template_index<0,T,P...> { using type = T; }; template <unsigned long long index,typename T,typename... P> struct variadic_type_template_index<index,T,P...> { using type = variadic_type_template_index<index-1,P...>::type; }; template <unsigned long long index,typename... T> using variadic_type_template_index_t = variadic_type_template_index<index,T...>::type; //Rest of the program #include <stdlib.h> // For malloc #include <iostream> // For std::cout template <template <unsigned long long,unsigned long long> typename tocall,unsigned long long initval,unsigned long long times> struct static_for; template <template <unsigned long long,unsigned long long> typename tocall,unsigned long long initval,unsigned long long times> requires requires(){tocall<initval,times>::toCall();} struct static_for<tocall,initval,times> { static_assert(initval<times,"Invalid static_for loop"); constexpr static void call() { tocall<initval,times>::toCall(); static_for<tocall,initval +1,times>::call(); } }; template <template <unsigned long long,unsigned long long> typename tocall,unsigned long long val> struct static_for<tocall,val,val> { constexpr static void call() {} }; template <typename... Args> struct loop_types { template <unsigned long long i,unsigned long long t> struct loop { using type = variadic_type_template_index_t<i,Args...>; static void toCall() { std::cout<<typeid(type).name()<<" "; } }; }; template <typename... Args> void call(Args...) { static_for<loop_types<Args...>::loop,0,sizeof...(Args)>::call(); } int main() { call("1",2,true,malloc(5)); }
报错信息
ToRun.cpp: In function 'void call(Args ...)': ToRun.cpp:67:59: error: type/value mismatch at argument 1 in template parameter list for 'template<template<long long unsigned int <anonymous>, long long unsigned int <anonymous> > class tocall, long long unsigned int initval, long long unsigned int times> struct static_for' 67 | static_for<loop_types<Args...>::loop,0,sizeof...(Args)>::call(); | ^ ToRun.cpp:67:59: note: expected a class template, got 'loop_types<Args ...>::loop' ToRun.cpp:67:66: warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse] 67 | static_for<loop_types<Args...>::loop,0,sizeof...(Args)>::call(); | ^~ ToRun.cpp:67:66: note: remove parentheses to default-initialize a variable 67 | static_for<loop_types<Args...>::loop,0,sizeof...(Args)>::call(); | ^~ | -- ToRun.cpp:67:66: note: or replace parentheses with braces to value-initialize a variable
修复方案
1. 核心错误原因与修复
在模板函数call中,loop_types<Args...>::loop是依赖于模板参数的嵌套类模板,编译器无法自动识别它是一个模板,必须用template关键字显式标注,消除语法歧义。
修改call函数:
template <typename... Args> void call(Args...) { // 增加template关键字,告诉编译器loop是一个模板 static_for<loop_types<Args...>::template loop, 0, sizeof...(Args)>::call(); }
2. 次要错误修复
原代码中std::cout的换行符写法错误(直接写" "),需要修正为标准的转义换行符"\n":
static void toCall() { std::cout << typeid(type).name() << "\n"; }
3. 可选优化(替换自定义类型索引)
你自定义的variadic_type_template_index可以用C++标准库的std::tuple_element替代,简化代码:
// 替换原有的variadic_type_template_index相关代码 #include <tuple> // 需要包含头文件 template <unsigned long long index, typename... T> using variadic_type_template_index_t = typename std::tuple_element<index, std::tuple<T...>>::type;
修复后运行结果
使用原编译命令g++ ToRun.cpp -o ToRun -std=c++23 && ./ToRun(Windows下为ToRun.exe),会输出各参数的 mangled 类型名称(GCC的typeid.name()输出格式):
PKc i b Pv
对应含义:PKc=const char*,i=int,b=bool,Pv=void*。
内容的提问来源于stack exchange,提问作者Supergamer
相关产品推荐
相关产品推荐

