Specialize a template with a template

后端 未结 2 667
隐瞒了意图╮
隐瞒了意图╮ 2021-01-21 06:31

I have a (free) function template that looks like this

template 
T get();

I now want to specialize this function for a class,

相关标签:
2条回答
  • 2021-01-21 07:16

    As Nawaz said, the standard just doesn't allow you to do that. You could however extract the implementation into the static method of a class and partially specialize that class.

    template<class T>
    struct get_impl{
      static T get(){ ... }
    };
    
    template<class T>
    struct get_impl<foo_type<T> >{
      static foo_type<T> get(){ ... }
    };
    
    template<class T>
    T get(){ return get_impl<T>::get(); }
    
    0 讨论(0)
  • 2021-01-21 07:34

    What you're doing is called partial specialization of function template. But partial specialization of function template is not allowed. Overloading of function template is allowed, but in this case, it is not possible either, as the function has only return type, and overloading on return type is not allowed.

    So the solution is this:

    namespace details
    {
         template <typename T>
         struct worker
         {
             static T get();
         };
    
         template <typename T> //partial specialization of class is allowed
         struct worker<foo<T>>
         {
             static foo<T> get();
         };
    
    }
    
    template <typename T>
    T get()
    {
      return details::worker<T>::get();
    }
    

    You could also use overloads if you define them to take one argument so as to make overload valid:

    namespace details
    {
         template <typename T>
         static T get(T*); 
    
         template <typename T> 
         static foo<T> get(foo<T>*); //now the overload is valid
    
    }
    
    template <typename T>
    T get()
    {
      return details::get<T>(static_cast<T*>(0));
    }
    

    Note that the argument static_cast<T*>(0) is used to help the compiler to select the correct overload. If T is other than foo<U>, then the first overload will be selected as the type of the argument passed to it will be T* as opposed to foo<U>*. If T is foo<U>, then the second overload will be selected by the compiler because it is more specialized, and can accept the argument passed to it which is foo<U>* in this case.

    0 讨论(0)
提交回复
热议问题