c++ - How to specialize a traits class for T as well as all of T's descendants -


i want make traits class apply type descedants. possible?

template <typename e> struct garble { };  template <typename t> struct wooble_traits;  template <typename e> struct wooble_traits<garble<e>> {   typedef e elem_type; };  struct intgarble : public garble<int> { };  typedef typename wooble_traits<intgarble>::elem_type igtype; //error, wooble_traits<intgarble> has no definition. 

is there way instead (borrowing , abusing java notation):

template <typename e> struct wooble_traits<? extends garble<e>> {   typedef e elem_type };  typedef typename wooble_traits<intgarble>::elem_type igtype; //fine, igtype alias int 

note:
attempting adapt dyp's solution example doesn't work since garble takes type parameter. there doesn't seem anywhere infer parameter.

#include <boost/type_traits/is_base_of.hpp>  template <typename t, typename c = void> struct wooble_traits;  template <typename t, typename e> struct wooble_traits<t, typename boost::is_base_of<garble<e>, t>::type> {   typedef e elem_type; }; 

in gcc-4.6 produces:

g++ -i/usr/include/boost/utility -i/usr/include/boost/type_traits -o0 -g3 -wall -c -fmessage-length=0 -mmd -mp -mf"main.d" -mt"main.d" -o "main.o" "../main.cpp" ../main.cpp:15:8: error: template parameters not used in partial specialization: ../main.cpp:15:8: error:         ‘e’ make: *** [main.o] error 1 

which understandable since there's no way gcc know value of e.

for base classes:

#include <type_traits>  template<bool b> using stdbool_t = std::integral_constant<bool, b>;  template<class t, class u = std::true_type> struct trait     : std::false_type {};  struct foo {}; struct bar : foo {};  template<class t> struct trait<t, stdbool_t<std::is_base_of<foo, t>{}>>     : std::true_type {};   #include <iostream>  int main() {     std::cout << std::boolalpha;      std::cout << trait<int>::value << "\n";     std::cout << trait<foo>::value << "\n";     std::cout << trait<bar>::value << "\n"; } 

for reason, specializing on non-type template parameters isn't allowed when expression depends on (the previous) type parameters.

g++4.8.2 fails compile btw (ice), works fine clang++3.5


here's alternative version compiles on both compilers:

template<class t, class = void> struct trait     : std::false_type {};  struct foo {}; struct bar : foo {};  template<class t> struct trait<t, typename std::enable_if<std::is_base_of<foo, t>{}>::type>     : std::true_type {}; 

the enable_if isn't necessary, actually. std::conditional work well, enable_if shorter here.


if base template specialization, can use jarod42's solution (i've modified bit):

template<template<class...> class t, class u> struct is_base_template_of { private:     template<class... v>     static auto test(const t<v...>&)         -> decltype(static_cast<const t<v...>&>(std::declval<u>()),                     std::true_type{});      static std::false_type test(...);  public:     static constexpr bool value =         decltype(is_base_template_of::test(std::declval<u>()))::value; };   template<class t> struct trait<t,              typename std::enable_if<is_base_template_of<foo, t>::value>::type>     : std::true_type {}; 

note: works public inheritance (and think has further restrictions: virtual , cases of multiple inheritance shouldn't work either).


here's version of same type trait in "c++03 + boost" style:

template<template<class> class t, class u> struct is_base_template_of { private:     typedef char false_type;     typedef char(& true_type)[2];      template<class v>     static true_type test(const t<v>*);     static false_type test(...);  public:     static const bool value =        (   sizeof(test(std::declval<typename std::remove_reference<u>::type*>()))         == sizeof(true_type)); }; 

Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -