c++ - Metaprogramming - Failed to specialize alias template -
third edit: today received email vs support stating it's know issue, has been fixed in vs2017. so, stick workaround time being.
i'm working on event system , wanted use metaprogramming save on typing. here's code:
struct foo { using type = int; }; struct bar { using type = char; }; template<typename... types> struct typelist {}; //this , getscript simplified, in reality involve messier templates... template<typename returntype> struct reqbuilder { using proxy = returntype(*)(void*, bool); // ... }; template<typename scripttype> using getscript = reqbuilder<scripttype>; template<typename list, template<typename> typename wrap> struct wraptypelist_impl {}; template<typename...ts, template<typename> typename wrap> struct wraptypelist_impl<typelist<ts...>, wrap> { using type = typelist<wrap< ts>...>; }; template<typename list, template<typename> typename wrap> using wraptypelist = typename wraptypelist_impl<list, wrap>::type; //use typedef using list1 = typelist<getscript<foo>, getscript<bar>>; //write manually using list2 = typelist<reqbuilder<foo>, reqbuilder<bar>>; //use wrapper wrap each element of typelist using list3 = wraptypelist<typelist<foo, bar>, getscript>;
goal have 3 list result in same typelist. code simplified, in reality getscript more work , it's useful. same reqbuilder contains more typedefs. so, list3 should easier write either list1 or list2.
there more getscript, reqbuilder-like classes , flattening of nested typelists. allows write list of possible events complex types.
this code above works - lists equal. problem when specialize (and want to) on nested type:
template<typename scripttype> using getscript = reqbuilder<typename scripttype::type>;
then following error atwraptypelist_impl::type=...
line:
error c2938 'getscript<unknown-type>' : failed specialize alias template
i have no idea means, has pack expansion, because when add specialization:
template<typename a,typename b, template<typename> typename wrap> struct wraptypelist_impl<typelist<a,b>, wrap> { using type = typelist<wrap<a>,wrap<b>>; };
then works nested types. so, have idea how working please?
i'm using visual studio 2015 comunnity edition. , more puzzling thing using intellisense - hovering on lists shows resolved in same typelist, std::is_same<list1,list3>::value
shows true
on hover. compiler reason disagrees.
edit: added full code causes said error
#include <algorithm> struct foo { using type = int; }; struct bar { using type = char; }; template<typename... types> struct typelist {}; //this , getscript simplified, in reality involve messier templates... template<typename returntype> struct reqbuilder { using proxy = returntype(*)(void*, bool); // ... }; template<typename scripttype> using getscript = reqbuilder<typename scripttype::type>; template<typename list, template<typename> typename wrap> struct wraptypelist_impl {}; template<typename...ts, template<typename> typename wrap> struct wraptypelist_impl<typelist<ts...>, wrap> { using type = typelist<wrap<ts>...>; }; template<typename list, template<typename> typename wrap> using wraptypelist = typename wraptypelist_impl<list, wrap>::type; using list1 = typelist<getscript<foo>, getscript<bar>>; using list2 = typelist<reqbuilder<typename foo::type>, reqbuilder<typename bar::type>>; using list3 = wraptypelist<typelist<foo, bar>, getscript>; int main() { constexpr bool = std::is_same<list1, list2>::value; constexpr bool b = std::is_same<list1, list3>::value; constexpr bool c = std::is_same<list2, list3>::value; static_assert(a, "list1 != list2"); static_assert(b, "list1 != list3"); static_assert(c, "list2 != list3"); }
erorrs:
1> main.cpp 1>main.cpp(23): error c2938: 'getscript<unknown-type>' : failed specialize alias template 1> main.cpp(31): note: see reference class template instantiation 'wraptypelist_impl<typelist<foo,bar>,getscript>' being compiled 1>main.cpp(23): error c3546: '...': there no parameter packs available expand 1>main.cpp(36): error c3203: 'typelist': unspecialized class template can't used template argument template parameter '_ty2', expected real type 1>main.cpp(37): error c3203: 'typelist': unspecialized class template can't used template argument template parameter '_ty2', expected real type 1>main.cpp(40): error c2338: list1 != list3 1>main.cpp(41): error c2338: list2 != list3
adding said a,b specialization wrapper after variadic 1 solves it.
second edit - found workaround
so, original problem still exists, after bit of trial , error, tried replace dependent type separate struct, seems solve problem:
template<typename scripttype> struct getscript_impl { using type = reqbuilder<typename scripttype::type>; }; template<typename scripttype> using getscript = typename getscript_impl<scripttype>::type; /* replacing code above template<typename scripttype> using getscript = reqbuilder<typename scripttype::type>; */
full code, works in vs2015 me: http://ideone.com/kgt4qm
as briefly stated in comment, think issue alias template using dependent type template argument not instantiate template or that.(i'm not template wizard, poke @ them, , see how respond).
i've found few links maybe related issue, didn't have time @ them yet(link1; link2; link3).
Comments
Post a Comment