我有一个(免费)功能模板,看起来像这样
template <typename T>
T get();
我现在想要为一个类专门化这个函数,它本身就是一个模板。但我的编译器不想编译它,我现在问这是否可能,以及我如何实现它。只是为了这个想法,代码可能如下所示:(不编译)
template <>
template <typename T>
foo_type<T> get<foo_type<T>>()
答案 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>*
。如果T
为foo<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(); }