2

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
    }
};

// specialized 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> // specialize the last boolean for true
{
public:
    using ObjectType = Object<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:
    virtual void Print() = 0; // only Print(), just for demo
};

// the default object which should not be instantiated
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<>
class Object<char, int, std::tuple, float, double, std::tuple> : public ObjectImpl<char, int, std::tuple, float, double, std::tuple>, 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?

foo
  • 398
  • 1
  • 16
  • 1
    That does only work for functions (MyCreator should be function not class) because there the template arguments are implicitly deduced and not explicitly given. Funnily enough, implicit deduction works (-> functions) and explicit specification (->class) is ambiguous (at least here in the context of multiple variadic parameter packs). – Andreas H. Nov 30 '20 at 10:21
  • 2
    How about have `MyCreator, std::tuple>>` syntax instead? – Jarod42 Nov 30 '20 at 10:25
  • `Object, U>` doesn't make sense. `Object` is declared to be a template that takes two templates as parameters, whereas you are passing two types. – Igor Tandetnik Nov 30 '20 at 17:32
  • 1
    In your example, you never seem to use `Args1` and `T` separately, but only as `T` combo (and similarly for `Args2` and `U`). So why take them separately? Why not `template `? – Igor Tandetnik Nov 30 '20 at 17:37

0 Answers0