Specialize a template with a template

蹲街弑〆低调 提交于 2019-12-02 01:00:16

问题


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

template <typename T>
T get();

I now want to specialize this function for a class, which itself is a template. But my compiler doesn't want to compile it, and I'm asking now if that is even possible and how I could achieve it. Just for the idea, the code could look as follows: (Doesn't compile)

template <>
template <typename T>
foo_type<T> get<foo_type<T>>()

回答1:


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.




回答2:


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(); }


来源:https://stackoverflow.com/questions/9542597/specialize-a-template-with-a-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!