vendredi 18 août 2017

Parameter pack not expanded when applied with metaprogramming

The main intention of this problem is to have a variable baseclass and then derived class chooses the base class using a variable(say int).

#include <iostream>


template<class T>
struct type_is
{
    using type = T;
};

template<uint16_t, class A, class, class>
struct IF_t : public A {};

template<class A, class B, class C>
struct IF_t<2, A, B, C> : public B {};

template<class A, class B, class C>
struct IF_t<3, A, B, C> : public C {};

class Base1
{
public:
void print()
{
    std::cout << "Base 1" << std::endl;
}
};

class Base2
{
public:
void print()
{
    std::cout << "Base 2" << std::endl;
}
};

class Base3
{
public:
void print()
{
    std::cout << "Base 3" << std::endl;
}
};

template <uint16_t q>
class Derived : public IF_t<q, Base1, Base2, Base3>
{
};

class MultipleBaseTemplateMetaProg {
public:
void print()
{
    Derived<1> aDerived1;
    aDerived1.print();
    Derived<2> aDerived2;
    aDerived2.print();
    Derived<3> aDerived3;
    aDerived3.print();
}
};


int main()
{
MultipleBaseTemplateMetaProg aMetaProg;
aMetaProg.print();
}   

The above code is working, but when I want to build the same using Variadic templates I am having issue with "packs not expanded" problem.

Here is the variadic template code,

#include <iostream>

template<class T>
struct type_is
{
using type = T;
};

template<uint16_t, class A, class ... B>
struct IF_t : public A {};

template<class A, class B, class ... C> // Problem here 
struct IF_t<2, A, B, C> : public B {};

template<class A, class B, class C, class ... D> // Problem here
struct IF_t<3, A, B, C, D> : public C {};

class Base1
{
public:
void print()
{
    std::cout << "Base 1" << std::endl;
}
};

class Base2
{
public:
void print()
{
    std::cout << "Base 2" << std::endl;
}
};

class Base3
{
public:
void print()
{
    std::cout << "Base 3" << std::endl;
}
};

template <uint16_t q>
class Derived : public IF_t<q, Base1, Base2, Base3>
{
};

class MultipleBaseTemplateMetaProg {
public:
void print()
{
    Derived<1> aDerived1;
    aDerived1.print();
    Derived<2> aDerived2;
    aDerived2.print();
    Derived<3> aDerived3;
    aDerived3.print();
}
};


int main()
{
MultipleBaseTemplateMetaProg aMetaProg;
aMetaProg.print();
}  

Aucun commentaire:

Enregistrer un commentaire