Search code examples
c++templatesc++11variadic-templatestemplate-templates

Merging types from variadic template using template-template arguments


I'm trying to extend a list of arguments being passed via a template template. The first example works, the second doesn't. The result I'm looking for would be that in the second example, cWapperObject.cMemberVariable.cTuple is of type std::tuple<double, float, short, int>. How can I achieve this? (And please, please do not mention the library boost in the comments or answers).

Example 1:

#include <tuple>

template<class ... TS> class CObject {
   std::tuple<TS ...> cTuple;
};

template<template<typename ... TS> class TMPL_CLASS_T>
class CWrapperObject {
    TMPL_CLASS_T<double, float, short> cMemberVariable;
};

int main() {
   CWrapperObject<CObject> cWapperObject;
   return 0;
}

Example 2:

#include <tuple>

template<class ... TS> class CObject {
   std::tuple<TS ...> cTuple;
};

template<template<typename ... TS> class TMPL_CLASS_T>
class CWrapperObject {
    TMPL_CLASS_T<double, float, TS ...> cMemberVariable;
};

int main() {
   CWrapperObject<CObject<short, int>> cWapperObject;
   return 0;
}

Solution

  • CObject is a class template, it can be used as a template-template argument. CObject<short, int> is a type, it can't be used as a template-template argument, neither a template-template parameter itself carries any actual type template arguments. You can still deduce the class template name and its parameters using a partial specialization, utilizing a template-template parameter, along with actual type template arguments that were used to instantiate the template:

    template <typename... TS>
    struct CObject
    {
        std::tuple<TS...> cTuple;
    };
    
    template <typename>
    struct CWrapperObject;
    
    template <template <typename...> class TMPL_CLASS_T, typename... TS>
    struct CWrapperObject<TMPL_CLASS_T<TS...>>
    {
        TMPL_CLASS_T<double, float, TS...> cMemberVariable;
    };
    

    DEMO