5

I need (want) to specialize a method inside a template class, to allow only certain primitive types. (This is not a duplicate question of this)

Well i've got this class :

template<typename TYPE, size_t NB>
class X
{
public:
   template<typename arg_type>
   X& get(const arg_type var);
}

I would like to specialize arg_type to allow only unsigned integers, something like this :

template<typename TYPE, size_t NB> template<unsigned long> X& X::get(const unsigned long val);

But sure, the above doesn't work, neither on msvc2011 nor on gcc

To be more specific, what i try to do is to write a code based on the templated type above, and write the specialization so that anyone using this class X cannot use this method with something else than what i specialized.

Is that even possible ? and if it is, is it bad to do it so ?

Thanks in advance, jav974

Community
  • 1
  • 1
jav974
  • 1,022
  • 10
  • 22
  • 1
    Why do you think that having the nested template is the best approach? While you can make this work, there might be cleaner simpler solutions, like not having a nested template and just non-template overloads... – David Rodríguez - dribeas Apr 22 '13 at 13:28

1 Answers1

4

A specialization is not what you want. Using a specialization you can provide a special way to treat the instantiation of your template method using an unsigned integral type, but nothing prevents the user from instantiating it with another type.

You can achieve this using some SFINAE:

#include <type_traits>    

template<typename TYPE, size_t NB> 
class X
{
public:
    template<typename arg_type> 
    typename std::enable_if<std::is_unsigned<arg_type>::value, X&>::type  // arg_type is unsigned
    get(arg_type val) 
    {

    }
};

You could also use static_assert, so that users get a more friendly error message:

template<typename arg_type> 
X& get(arg_type val) 
{
    static_assert(std::is_unsigned<arg_type>::value, "The argument should be unsigned!");
}

If you want the TYPE template parameter to follow the same rules, you could also use static_assert:

template<typename TYPE, size_t NB> 
class X
{
public:
    static_assert(std::is_unsigned<TYPE>::value, "TYPE should be unsigned!");
};
mfontanini
  • 21,410
  • 4
  • 65
  • 73
  • Awesome !! i didn't know about that, thank you very much !! By the way the 'TYPE' for the class should also follow the same rules, where should i put this check ? ctor ? – jav974 Apr 22 '13 at 13:12