when using sfinae select constructor overloads in past, have typically used following:
template <typename t> class class { public: template <typename u = t, typename std::enable_if<std::is_void<u>::value, int>::type=0> class() { std::cout << "void" << std::endl; } template <typename u = t, typename std::enable_if<!std::is_void<u>::value, int>::type=0> class() { std::cout << "not void" << std::endl; } };
however, came across alternative:
template <typename u = t, typename std::enable_if<std::is_void<u>::value>::type...> class() { std::cout << "void" << std::endl; }
considering following illegal ...
template <typename u = t, void...> // error! class() { }
... how alternative above using ellipses rather non-type template argument work?
full code: http://coliru.stacked-crooked.com/a/64a1aaf13ce6099b
my previous answer wrong. sorry. i'm going fix it.
this declaration:
template <typename u = t, void...> class() { }
violates [temp.res]/8:
the program ill-formed, no diagnostic required, if [...] every valid specialization of variadic template requires empty template parameter pack
it's no diagnostic required, compiler chooses issue 1 anyway. either way, code ill-formed.
on other hand
template <typename u = t, std::enable_if_t<std::is_void<u>::value>...> class() { }
doesn't violate requirement. have empty pack, don't run afoul of fact can't use void
non-type template parameter. additionally, hypothetical specialization of enable_if
provide type isn't void
there it's not ill-formed due above limitation.
Comments
Post a Comment