I would like to pass a std::initializer_list inside a variable number of arguments for a function that print each argument.
func( 1, 2.5, 'a', "Hello", {10, 20, 30, 40 } );
Expecting this output:
1
2.5
a
Hello
{ 10, 20, 30, 40, }
I tried to implement it following this answer from another question.
#include <iostream>
#include <initializer_list>
template <typename T>
void func_(std::initializer_list<T> list )
{
std::cout << "{ ";
for( const T& elem : list )
{
std::cout << elem << ", ";
}
std::cout << "}" << std::endl;
}
template <typename T>
void func_(T t)
{
std::cout << t << std::endl;
}
void func(){}
template<typename T, typename... Args>
void func(T t, Args... args) // recursive variadic function
{
func_(t);
func(args...) ;
}
int main()
{
func( 1,2.5,'a', "Hello", {10, 20, 30, 40 });
}
Another way that I tried to implemented func
template <typename T, typename S>
void func(T t)
{
if constexpr (std::is_same<T, std::initializer_list<S>>::value)
{
std::cout << "{ ";
for( const S& elem : t )
{
std::cout << elem << ", ";
}
std::cout << "}" << std::endl;
}
else
std::cout << t << std::endl;
}
template<typename T, typename... Args>
void func(T t, Args... args) // recursive variadic function
{
func(t);
func(args...);
}
None of them worked
The problem is that a braced init list does not have a type. So we have to explicitly specify the type specifier.
The simplest way I can think of is to create a class with an
std::initializer_listctor and overloadedoperator<<and then use it as shown below.Working demo
The output of the above program is(the same as your expected output):
It can be further customized as per your needs.