Home:ALL Converter>How to specialize a class for an inner type of a template?

How to specialize a class for an inner type of a template?

Ask Time:2017-01-20T05:38:57         Author:Myria

Json Formatter

I have a class that acts as a type trait, returning whether a certain condition is true. It's intended to mark classes as supporting a particular feature.

template <typename T> struct Check : std::false_type { };

I have a template class that contains an inner class:

template <unsigned N>
struct Kitty
{
  struct Purr;
};

I want to mark the inner class Purr as supporting the feature denoted as Check. In other words, I want to make it so that Check<Kitty<123>::Purr>::value is true. I tried doing the following, but I get an error:

template <unsigned X>
struct Check<typename Kitty<X>::Purr> : std::true_type { };

error: template parameters not deducible in partial specialization:

Is it possible to accomplish this, or is it a limitation of C++ that you can't specialize on inner template class members?

Author:Myria,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/41752187/how-to-specialize-a-class-for-an-inner-type-of-a-template
chris :

As outlined in my comment, it is possible to make this a deduced context by using a base class, which I'll call KittyBase. Using a base class is actually common for templates, to avoid having unnecessary code duplicated for every new instantiation. We can use the same technique to get Purr without needing to deduce N.\n\nHowever, simply putting Purr in the base class will remove its access to N. Fortunately, even in making Purr itself a template, this can still be a non-deduced context: Live example\n\n#include <type_traits>\n\ntemplate <typename T> struct Check : std::false_type { };\n\nstruct KittyBase \n{ \n template<unsigned N> // Template if Purr needs N.\n struct Purr;\n\nprotected:\n ~KittyBase() = default; // Protects against invalid polymorphism.\n};\n\ntemplate <unsigned N>\nstruct Kitty : private KittyBase\n{\n using Purr = KittyBase::Purr<N>; // Convenience if Purr needs N.\n Purr* meow;\n};\n\ntemplate <unsigned X>\nstruct Check<typename KittyBase::Purr<X>> : std::true_type { };\n\nstatic_assert(not Check<int>{});\nstatic_assert(Check<Kitty<123>::Purr>{});\nstatic_assert(Check<Kitty<0>::Purr>{});\n\nint main() {}\n\n\nIf you wish, you can even make KittyBase::Purr private and use template<typename T> friend struct Check; to grant access to the trait. Unfortunately, I don't know whether you can limit that to only certain specializations of the trait.",
2017-01-19T22:20:50
yy