I have this code in which static_for
can be used as a compile-time loop using template-metaprogramming and loop_types
is a struct
accepting variadic arguments.
Whenever I try to call the function call
, it give me an error.
In loop_types
, the is a template loop
contain the function that prints name of the types.
//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()<<"\n";
}
};
};
template <typename... Args>
void call(Args...)
{
static_for<loop_types<Args...>::loop,0,sizeof...(Args)>::call();
}
int main()
{
call("1",2,true,malloc(5));
}
Error message I get
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
How can I fix this problem?
Also, in case I replace Args...
with a number of types ifself like with int,char,bool
along with specifying number of types itself, the code works properly.
Compiler used - GCC
Command used
g ToRun.cpp -o ToRun -std=c 23 && "ToRun.exe"
I was expecting the program to print the types' name of every parameter I passes to call
CodePudding user response:
For call()
function... passing through a using
should solve the problem
template <typename... Args>
void call(Args...)
{
using for_t = static_for<loop_types<Args...>::template loop, 0, sizeof...(Args)>;
for_t::call();
}
but remember to add a couple of typename
in variadic_type_template_index
specialization and using
template <unsigned long long index,typename T,typename... P>
struct variadic_type_template_index<index,T,P...>
{
using type = typename variadic_type_template_index<index-1,P...>::type;
// ..........^^^^^^^^
};
template <unsigned long long index,typename... T>
using variadic_type_template_index_t = typename variadic_type_template_index<index,T...>::type;
// ....................................^^^^^^^^
and also a dummy variadic_type_template_index<0>
specialization, by example
template <>
struct variadic_type_template_index<0>
{
using type = void;
};
or you get a compilation error from
requires requires(){tocall<initval,times>::toCall();}
when initval
is equal to times