我有如下定义的类成员函数,为其中一个提供规范,并让用户为其他人提供自己的规范:
template <typename T>
class Foo {
// specialization provided for integral types
template <typename Enable = T>
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
bar(const T& value);
// provide your own specialization for other types
template <typename Enable = T>
typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type
bar(const T& value);
};
template <typename T>
template <typename Enable>
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
Foo<T>::bar(const T& value) {
...
}
现在,我想提供适用于整数对类型的函数的特化。我有一个模板元函数检查整数对,定义如下:
template <typename T>
struct is_integral_pair : std::false_type {};
template <typename T1, typename T2>
struct is_integral_pair<std::pair<T1, T2>> {
static const bool value =
std::is_integral<T1>::value && std::is_integral<T2>::value;
};
我是否可以提供自己的专业化,使其适用于所有整数对,可能使用我在上面定义的模板元函数?
答案 0 :(得分:0)
这是一个人为的例子,有点难以理解。但是,通过基本更改,您可以轻松添加所需内容。首先要注意的是,您在上面定义的内容不是bar
的部分特化(这是不可能的,因为您不能部分地专门化一个函数)而是重载。接下来,你有一个人为的系统,你有一个Enable
参数与函数参数无关 - 这真的是你的意图吗?如果您更改了函数的模板参数与其变量参数的类型相同,则问题变得简单 - 您为整数对添加另一个重载,再次使用SFINAE来帮助您。以下是实现所需内容的示例方法:
#include <iostream>
template <typename T>
class Foo {
public:
// specialization provided for integral types
template <typename Enable>
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
bar(const Enable& value);
// provide your own specialization for other types
template <typename Enable>
typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type
bar(const Enable& value);
// provide your own specialization for integral pairs
template <typename U, typename V>
typename std::enable_if<std::is_integral<U>::value && std::is_integral<V>::value, size_t>::type
bar(const std::pair<U,V>& value);
};
template <typename T>
template <typename Enable>
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
Foo<T>::bar(const Enable& value)
{
std::cout << "Integral" << std::endl;
return 0;
}
template <typename T>
template <typename Enable>
typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type
Foo<T>::bar(const Enable& value)
{
std::cout << "Non-Integral" << std::endl;
return 0;
}
template <typename T>
template <typename U, typename V>
typename std::enable_if<std::is_integral<U>::value && std::is_integral<V>::value, size_t>::type
Foo<T>::bar(const std::pair<U,V>& value)
{
std::cout << "Integral pair" << std::endl;
return 0;
}
int main()
{
Foo<int> foo;
foo.bar(1); //output "Integral"
foo.bar(1.0); //output "Non-Integral"
foo.bar(std::pair<float, int>(1.0, 1)); //output "Non-integral"
foo.bar(std::pair<long, int>(1, 1)); //output "Integral pair"
return 0;
}