You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

可变参数模板参数传递至另一模板报错,求修复方案

问题:编译时模板循环调用报错修复

我用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 10:40:37