lundi 30 novembre 2020

Template Class with Multiple Variadic Parameter Packets

I want to ask how a template class could have Variadic Parameter Packets.

I'm writing a template creator for building template objects. and the object must accept 2 variadic parameter packets.

If I have specialize the object, this object would be created, otherwise, an empty object be returned from the creator.

Here is the demo code and the use case.

#include <iostream>
#include <memory>

// defualt creator which returns empty object
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U,
    template<template<typename...> typename, 
             template<typename...> typename> typename Object, // the object must accpet 2 variadic parameter packets
    bool = Object<T<Args1...>, U<Args2...>>::value>           // the boolean is for specilization
class MyCreator
{
public:
    using ObjectType = Object<T<Args1...>, U<Args2...>>;

    template<typename... Args>
    static std::unique_ptr<ObjectType> New(Args&&...)
    {
        return std::unique_ptr<ObjectType>(); // returns a empty object
    }
};

// specalized creator which returns a real one
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U,
    template<template<typename...> typename, 
             template<typename...> typename> typename Object>
class MyCreator<Args1..., T, Args2..., U, Object, true> // specalize the last boolean for true
{
public:
    using ObjectType = Solver<T<Args1...>, U<Args2...>>;

    template<typename... Args>
    static std::unique_ptr<ObjectType> New(Args&&...args)
    {
        return std::make_unique<ObjectType>(std::forward<Args>args...); // returns a real object
    }
};

// the interface for object
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U
class ObjectImpl : public std::false_type
{
public:
    virtual void Print() = 0; // only Print(), just for demo
};

// the default object which should not be instantiate
template<
    typename... Args1, template<typename...> typename T,
    typename... Args2, template<typename...> typename U
class Object : public ObjectImpl<Args1..., T, Args2..., U>, public std::false_type
{
};

// the specilized object which could be instantiated, just for demo
template<
    char,  int,    std::tuple,
    float, double, std::tuple,
class Object : public ObjectImpl<Args1..., T, Args2..., U>, public std::true_type
{
public:
    void Print() override
    { 
        std::cout<< std::tuple_size<std::tuple<char, int>>::value << std::endl;
        std::cout<< std::tuple_size<std::tuple<float, double>>::value << std::endl;
    };
};

// use case
int main()
{
    // create obj using creator
    auto obj = MyCreator<char,  int,    std::tuple
                         float, double, std::tuple,
                         Object>().New();

    // call the obj if enable
    if(obj)
    {
        obj->Print();   
    }

    return 0;
}

I have found an answer for tempalate fuction How can I have multiple parameter packs in a variadic template? but could not fix the issue for template class with the Variadic Parameter Packets?

Aucun commentaire:

Enregistrer un commentaire