使用模板专门化模板

时间:2012-03-03 01:35:52

标签: c++ templates specialization

我有一个(免费)功能模板,看起来像这样

template <typename T>
T get();

我现在想要为一个类专门化这个函数,它本身就是一个模板。但我的编译器不想编译它,我现在问这是否可能,以及我如何实现它。只是为了这个想法,代码可能如下所示:(不编译)

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

2 个答案:

答案 0 :(得分:4)

您正在做的事情被称为功能模板的部分专业化。但是不允许部分功能模板专门化。允许重载函数模板,但在这种情况下,它也是不可能的,因为函数只有返回类型,并且不允许在返回类型上重载。

所以解决方案就是:

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

如果您将它们定义为采用一个参数以使过载有效,您也可以使用重载:

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

请注意,参数static_cast<T*>(0)用于帮助编译器选择正确的重载。如果T不是foo<U>,则会选择第一个重载,因为传递给它的参数类型将是T*而不是foo<U>*。如果Tfoo<U>,那么编译器将选择第二个重载,因为它是 more 专用的,并且可以接受传递给它的参数{{1}在这种情况下。

答案 1 :(得分:2)

正如Nawaz所说,标准只是不允许你这样做。但是,您可以将实现提取到类的静态方法中,并部分地专门化该类。

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