dimanche 24 septembre 2017

C++ template declaration that restricts specializations too much

I'll try to explain my current problem briefly. It could be solved easily but the only solution I've found until now doesn't satisfy myself, maybe you'll indicate to me the next level of indirection that would be needed for resolution.

I use CRTP here, even if that's not the crux of the issue. Here is a piece of code that reproduces my problem :

template <typename T>
class A
{
    public:
        static void p()
        {
            T::p();
        }
};

template <typename T>
class B
{
    public:
        static void q()
        {
            T::q();
        }
};



????? template <??????> ???? // How to declare C here ??? 
class C;


//now first specializations with A
template <int a>
class C<a> : public A<C<a> >
{
    public:
        static void p()
        {
            //specific stuff
        }
};

template <int a, typename Other_handlers ...>
class C<a, Other_handlers...> : public A<C<a, Other_handlers...> >
{
    public:
        static void p()
        {
            //specific stuff
        }
};

template <int a, typename Child>
class C<a, B<Child> > : public A<C<a, B<Child> > >
{
    public:
        static void p()
        {
            //specific stuff
        }
};



//second specializations with B
template <int a, int b>
class C<a, b> : public B<C<a, b> >, C<a>
{
    public:
        static void q()
        {
            //specific stuff
        }
};

template <int a, int b, typename Other_handlers ...>
class C<a, b, Other_handlers...> : public B<C<a, b, Other_handlers...> >, C<a>
{
    public:
        static void q()
        {
            //specific stuff
        }
};

template <int a, int b, typename Child>
class C<a, b, B<Child> > : public B<C<a, b, B<Child> > >, C<a>
{
    public:
        static void p()
        {
            //specific stuff
        }
};

The goal of this piece of code would be to have some methods in C that depends on template parameters (here C<1,2> would have methods of both A and B class, whereas C<1> would only have ones of A, then C<1, C<1,2> > would have only ones of A, whereas C<1, 2, C<3> > would have both, etc ...). Where I fail is at the declaration of C before its specialization, because I don't know how to declare something that would be generic enough to support both values and type template parameters (in this case int values and types, mixed). Because if I declare

template <typename ... Args>
class C;

it obviously fails parsing ints.

And

template <int a, int b, typename ... Args>
class C;

obviously fails parsing types in specialization with only one int parameter.

So, the only solution I've found until now is to declare 2 different types instead of C :

template <int a, typename ... Args> // allows first specialisations
class C;
template <int a, int b, typename ... Args> //allows second specialisations
class D;

But I would like to group into only one declaration. Is it possible ?

Thank you in advance !

PS : By the way the title I chose is very bad, if you have any better suggestion for it let me know !

Aucun commentaire:

Enregistrer un commentaire