我想专注于以下模板:
template <typename T, int P>
T item(size_t s);
这样的事情:
template<int P>
T item<typename T>(size_t s)
{
//for all numeric types
return static_cast<T>(rand());
}
template <int P>
string item<string>(size_t s)
{
return "asdf";
}
答案 0 :(得分:5)
你不能部分专门化这样的功能模板。模板部分特化仅适用于类模板。
但是,您可以使用boost::enable_if
来“模拟”您正在寻找的功能模板部分特化。
// Specialization for std::string
//
template <int P, typename T>
T item(size_t, typename boost::enable_if<boost::is_same<T, std::string> >::type* = 0)
{
....
}
// Specialization for int
//
template <int P, typename T>
T item(size_t, typename boost::enable_if<boost::is_same<T, int> >::type* = 0)
{
....
}
这样,如果你调用item<5, std::string>(10)
,你将调用第一个函数,如果你调用item<5, int>(10)
,你将调用第二个函数。
或者,如果您出于某种原因不想使用Boost,另一种解决方法是创建一个调度程序类模板,当然可以部分专用。
答案 1 :(得分:1)
两者都需要部分专业化。第一个是要求SFINAE。由于函数模板只能完全专用,因此您必须使用某种类型的辅助对象。
template <typename T, int P>
T item(size_t s);
template < typename T, typename Enable = void >
struct item_
{
template < int P >
T apply(size_t s);
};
template < typename T >
struct item_<T, typename enable_if< is_numeric<T> >::type >
{
template < int P >
static T apply(size_t s) { return static_cast<T>(rand()); }
};
template < >
struct item_<std::string, void>
{
template < int P >
static std::string apply(size_t s) { return "NSTHEOSUNTH"; }
};
template < typename T, int P >
T item(size_t s) { return item_<T>::template apply<P>(s); }
或者您可以考虑标记调度:
struct numeric_tag {};
struct string_tag {};
struct wtf_tag {};
template < typename T, int P >
T item(size_t s, numeric_tag) { return static_cast<T>(rand()); }
template < typename T, int P >
T item(size_t s, string_tag) { return "SNTHEO"; }
template < typename T, int P >
T item(size_t s)
{
item(s, if_
<
is_numeric<T>
, numeric_tag
, typename if_
<
is_same< std::string, T >
, string_tag
, wtf_tag
>::type
>::type());
}
或者你可以混合一些元函数类来匹配标签并使用对向量...迭代通过它们测试每个(元函数类)并返回第二个(标签)来选择实现。
有很多很多方法可以解决这个问题。
答案 2 :(得分:-4)
为了清楚起见:您无法专门处理功能模板 。你可以超载它们,你不能把它们专门化。
正确绑定功能模板的部分特化(如果存在)将由以下内容给出:
template<class T, class U> X f(T,U);
specialise template<class A, class B> X f(A,B)
with template <class K> <K,K*>;
模板类有一个更容易的专业化规范,因为它们是由名称,函数重载唯一标识的,所以这还不够。