c++ - template specialization for derived classes -
i have template class (that cannot modify), let's call someclass
, i'd specialize classes derive particular class only. following this answer able in gcc 6.3.1, unfortunately need in gcc 4.9.2, , there fails @ compile time saying "partial specialization someclass<t>
not specialize template arguments".
is there way change below make work gcc 4.9.2?
#include <iostream> #include <string> using namespace std; struct { string name() { return "a"; } }; struct b : { string name() { return "b"; } }; struct c { string name() { return "c"; } }; template<typename t, typename = std::enable_if_t<std::is_base_of<a, t>::value>> using enable_if_a = t; template<typename t> struct someclass { using type = t; }; template<typename t> struct someclass<enable_if_a<t>> { using type = a; }; int main(int, char**) { someclass<a>::type el1; someclass<b>::type el2; someclass<c>::type el3; cout << el1.name() << "," << el2.name() << "," << el3.name() << endl; }
output:
a,a,c
a bit contrived, here machinery @ least works.
basic idea hide a
, not inherit directly it. instead, can heavily rely on mixins , combine few classes in detector can specialize someclass
.
drawback classes b
become more abstruse , i'm not sure it's worth @ end of day. direct specializations better.
that being said, here working example:
#include <iostream> #include <string> #include <utility> using namespace std; class aderivedfactory { struct { string name() { return "a"; } }; template<typename t> struct detector: t { using type = a; }; public: template<template<typename> class c> using type = detector<c<a>>; }; template<typename t> struct @ : t {}; template<typename t> struct bt : t { string name() { return "b"; } }; using = aderivedfactory::type<at>; using b = aderivedfactory::type<bt>; struct c { string name() { return "c"; } }; template<typename t> struct someclass { using type = t; }; template<template<typename> class c> struct someclass<aderivedfactory::type<c>> { using type = typename aderivedfactory::type<c>::type; }; int main(int, char**) { someclass<a>::type el1; someclass<b>::type el2; someclass<c>::type el3; cout << el1.name() << "," << el2.name() << "," << el3.name() << endl; }
see , running on wandbox.
Comments
Post a Comment