c++ - Variadic template argument within template template parameter in a partial specialization -


i trying develop generic code can select different containers types (std::vector, std::map, other), , perform operations on container wrapper, got stuck following code:

enum class econtainnertype {     econtainnertype_normal,     econtainnertype_or,     econtainnertype_and };  // base declaration template<econtainnertype, template<class ... > class containertype, class ... argtype > struct conditioncontainnertype { };  // partial specialization     template< template<class ... > class containertype, class ... argtype > struct conditioncontainnertype<econtainnertype::econtainnertype_or, containertype<argtype ... >, argtype ...> { };     int main() {     return 0; } 

the variadic template template argument not compile, , error:

main.cpp:33:108: error: wrong number of template arguments (2, should 3)  struct conditioncontainnertype<econtainnertype::econtainnertype_or,typename containertype<argtype>, argtype>                                                                                                             ^  main.cpp:29:8: error: provided 'template<econtainnertype <anonymous>, template<class> class containertype, class argtype> struct conditioncontainnertype'  struct conditioncontainnertype 

goal:

the main goal of implementation perform kind of operation of classification (or, and, xor), operation performed on element compared against generic container.

the operation type defined enum class, , partial specialization selected action.

so, if have set {a,b,c,d,e} , fill set specific combination of elements say: generic_container<operation_type,generic_set_element> want generic conditional container perform action selected "operation type". if element x compared against set, generic container can perform preselected action on x element.

the problem cannot specialize template-template parameter template-template parameter given template arguments, forcing:

containertype<args...> 

to match:

template <typename...> class basecontainertype 

because no longer template template argument. instead, plain containertype name need used here, without <args...> part:

// base declaration template <template <typename...> class containertype> struct conditioncontainnertype { };  // partial specialization two-parameter template template parameter template <template <typename, typename> class containertype> struct conditioncontainnertype<containertype> { };   

you can, however, specialize template type template-template parameter filled arguments (even expanded parameter pack), goes follows:

// base declaration template <econtainnertype, typename containertype, typename... args> //                         ^^^^^^^^^^^^^^^^^^^^^^^ normal type here struct conditioncontainnertype { };  // partial specialization template <template <typename...> class containertype, typename... args> //        ^^^^^^^^ template here struct conditioncontainnertype<econtainnertype::econtainnertype_or,                                containertype<args...>, //                                           ^^^^^^^ expanded parameter pack                                args...> { };   

or without trailing parameter pack:

template <template <typename...> class containertype, typename... args> struct conditioncontainnertype<econtainnertype::econtainnertype_or,                                containertype<args...>> { };   

as specialize templated containers std::vector<t, a> take 2 parameters: type t , allocator a:

template <template <typename, typename> class containertype, typename t, typename a> struct conditioncontainnertype<econtainnertype::econtainnertype_or,                                containertype<t, a>,                                t> { };   

tests:

int main() {     // base, , not match or     conditioncontainnertype<econtainnertype::econtainnertype_and                            , mycontainer<int>                            , int>{};      // specialized, or , parameter pack matches     conditioncontainnertype<econtainnertype::econtainnertype_or                            , mycontainer<int>                            , int>{};      // base, or matches, parameters packs not     conditioncontainnertype<econtainnertype::econtainnertype_or                            , mycontainer<float>                            , int>{};      // vector, or , parameter pack matches     conditioncontainnertype<econtainnertype::econtainnertype_or                            , std::vector<int>                            , int>{};      // or , no parameter-pack     conditioncontainnertype<econtainnertype::econtainnertype_or                            , std::vector<int>>{}; } 

demo


if otherwise aim specialize base declaration depending on concrete container type (std::vector, std::map), can follows:

// base declaration template <econtainnertype, template <typename...> class containertype> struct conditioncontainnertype { };  // partial specialization std::vector template <> struct conditioncontainnertype<econtainnertype::econtainnertype_or, std::vector> //                                                                  ^^^^^^^^^^^ { };  // partial specialization std::map template <> struct conditioncontainnertype<econtainnertype::econtainnertype_and, std::map> //                                                                   ^^^^^^^^ { };   

tests:

int main() {     // first specialization     conditioncontainnertype<econtainnertype::econtainnertype_or, std::vector>{};      // second specialization     conditioncontainnertype<econtainnertype::econtainnertype_and, std::map>{}; } 

demo 2


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

jsf - How to ajax update an item in the footer of a PrimeFaces dataTable? -

django - CSRF verification failed. Request aborted. CSRF cookie not set -