overlord
overlord

Reputation: 499

Determining Max Size Of Variadic Template Class Instance in Compile Time in C++

I want to determine max size of following variadic template class instance in compile time.

template <typename... T>
class Foo
{
public:

    std::tuple<T...> params;
    void (*func)(T...);

    void save(T...args)
    {
        params=std::make_tuple(args...);
    }

    void call()
    {
        std::apply(func,params);
    }
};

I want to use this class as follow:

void testfoo1(int a,double b,double c,double d)
{
    std::cout<<a<<"--"<<b<<c<<d<<std::endl;
}

void testfoo2(int a,double b,double c,double d,int e,long long int f)
{
    std::cout<<a<<"--"<<b<<c<<d<<e<<f<<std::endl;
}
struct FooObject
{
    char buffer[MAX_SIZE_FOO_OBJECT];
};

int main()
{
    std::queue<FooObject> fooObjectBuffer;
    FooObject foo_temp;
    Foo<int,double,double,double> foo1;
    Foo<int,double,double,double,int,long long int> foo2;
    foo1.func=testfoo1;
    foo1.save(5,10.2,5.3,2.7);
    foo2.func=testfoo2;
    foo2.save(1,2,3,4,5,6);
    fooObjectBuffer.push(*reinterpret_cast<FooObject*>(&foo1));
    fooObjectBuffer.push(*reinterpret_cast<FooObject*>(&foo2));

    foo_temp=fooObjectBuffer.front();
    reinterpret_cast<decltype (foo1)*>(&foo_temp)->call();
    fooObjectBuffer.pop();
    fooObjectBuffer.front();
    foo_temp=fooObjectBuffer.front();
    reinterpret_cast<decltype (foo2)*>(&foo_temp)->call();
    fooObjectBuffer.pop();
}

I need to know MAX_SIZE_FOO_OBJECT value to do this in compile time. What can I do to know MAX_SIZE_FOO_OBJECT value in compile time?

Upvotes: 1

Views: 474

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473447

It's a template; unless you provide some specific restriction on the various Ts that can go in Foo, anyone can instantiate it with any type which can be a member of a std::tuple and otherwise fits your interface. The set of Ts is unbounded and therefore unknowable. Which means any operation on the various possible Ts (like computing the maximum size) is equally unknowable.

You can only know this if you have some fixed, bounded set of valid Ts that you intend to use. Even with that, you would need a lot of template metaprogramming to compute the size of every Foo instantiated with every combination of this set of Ts.

It's best to just avoid this altogether and do something much more type-safe. Or failing that, pick a maximum size you're comfortable with and just static_assert somewhere if someone tries to instantiate Foo with types that exceed this size.

Upvotes: 1

Related Questions