Consider this function template:
template 
void foo (std::tuple ... x);
  This invocation works:
Generate an overloaded set of constructors:
#include 
#include 
template 
using indexed = T;
template 
struct initializer : initializer
{    
    using initializer::initializer;
    initializer(indexed... ts)
    {
        // ts is a pack of std::tuple
    }
};
template 
struct initializer {};
using foo = initializer, 20>;
//                                   tuples limit+1 ~~~^
int main()
{
    foo({1,'2',3.0});
    foo({1,'2',3.0}, {4,'5',6.0});
    foo({1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0});
}
           DEMO
Generate an overloaded set of function call operators:
#include 
#include 
template 
using indexed = T;
template 
struct initializer : initializer
{    
    using initializer::operator();
    int operator()(indexed... ts) const
    {            
        // ts is a pack of std::tuple
        return 1;
    }
};
template 
struct initializer
{
    int operator()() const { return 0; }
};
static constexpr initializer, 20> foo = {};
//                                        tuples limit+1 ~~~^
int main()
{    
    foo({1,'2',3.0});
    foo({1,'2',3.0}, {4,'5',6.0});
    foo({1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0});
}
           DEMO 2
Create (or generate with preprocessor macros) a set of overloads that forward arguments to a single implementation:
#include 
#include 
using K = std::tuple;
void foo(const std::array& a)
{
    // a is an array of at most 5 non-null std::tuple*
}
void foo(K p0) { foo({&p0}); }
void foo(K p0, K p1) { foo({&p0, &p1}); }
void foo(K p0, K p1, K p2) { foo({&p0, &p1, &p2}); }
void foo(K p0, K p1, K p2, K p3) { foo({&p0, &p1, &p2, &p3}); }
void foo(K p0, K p1, K p2, K p3, K p4) { foo({&p0, &p1, &p2, &p3, &p4}); }
int main()
{
    foo({1,'2',3.0});
    foo({1,'2',3.0}, {4,'5',6.0});
    foo({1,'2',3.0}, {4,'5',6.0}, {7,'8',9.0});
}
     DEMO 3
Pass as an array and deduce its size (requires additional pair of parens):
#include 
#include 
template 
void foo(const std::tuple (&a)[N])
{
    // a is an array of exactly N std::tuple
}
int main()
{
    foo({{1,'2',3.0}, {4,'5',6.0}});
 //     ^~~~~~ extra parens ~~~~~^
}
     DEMO 4
Use an std::initializer_list as a constructor parameter (to skip extra parens):
#include 
#include 
struct foo
{
    foo(std::initializer_list> li)
    {
        // li is an initializer list of std::tuple
    }
};
int main()
{
    foo{ {1,'2',3.0}, {4,'5',6.0} };
}
    DEMO 5