我有一个(免费)函数模板,看起来像这样专业生产与模板
template <typename T>
T get();
我现在要专注这个功能的一类,这本身就是一个模板,模板。但是我的编译器不想编译它,现在我问的是否可能,以及我如何实现它。只是为理念,代码可能看起来如下:(不编译)
template <>
template <typename T>
foo_type<T> get<foo_type<T>>()
我有一个(免费)函数模板,看起来像这样专业生产与模板
template <typename T>
T get();
我现在要专注这个功能的一类,这本身就是一个模板,模板。但是我的编译器不想编译它,现在我问的是否可能,以及我如何实现它。只是为理念,代码可能看起来如下:(不编译)
template <>
template <typename T>
foo_type<T> get<foo_type<T>>()
你在做什么叫做部分专业化功能模板。但是部分功能模板的专门化是不允许的。函数模板的重载是允许的,但在这种情况下也是不可能的,因为函数只有返回类型,并且不允许重载类型的重载。
因此,解决办法是这样的:
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>
,那么第二个重载将由编译器选择,因为它是更多专用的,并且可以接受在此情况下传递给它的参数,即foo<U>*
。
正如纳瓦兹表示,该标准只是不允许你这样做。但是,您可以将实现提取到类的静态方法中,并部分专门化该类。
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(); }
现在,看到解决方案,这是显而易见的痛苦。谢谢!但现在我得到一个链接器错误..任何想法? – cooky451 2012-03-03 01:45:06
错误,基于返回类型的重载不起作用... – Xeo 2012-03-03 01:45:15
@Xeo:糟糕。是。你是对的。当我发布它时,我觉得我做错了什么,但是搞不清楚。 – Nawaz 2012-03-03 01:46:50