用于多种类型的重写成员函数的模板部分专业化 [英] Template partial specialization for multiple types overriding member function

查看:49
本文介绍了用于多种类型的重写成员函数的模板部分专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有如下定义的类成员函数,为其中一个提供了规范,并让用户为其他提供了自己的规范:

I have class member functions defined as follows, providing a specification for one of them and letting the user provide their own specification for others:

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) {
    ...
}

现在,我想为该函数提供一个特殊化适用于整数对类型。我有一个模板元函数,用于检查如下定义的整数对:

Now, I'd like to provide a specialization for the function that will work for integral pair types. I have a template metafunction checking for integral pairs defined as follows:

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

我是否有可能提供自己的专业知识,使其适用于所有整数对,也许使用我上面定义的模板元功能?

Is it possible for me to provide my own specialization such that it works for all integer pairs, perhaps using the template metafunction I defined above?

推荐答案

这是一个人为的示例,有点难以理解。但是,通过基本更改,可以轻松添加所需的内容。首先,重要的是要注意,您在上面定义的不是 bar 的部分专业化(这是不可能的,因为您不能部分地对函数进行专业化),而是重载。接下来,您有一个精心设计的系统,其中有一个与功能参数无关的 Enable 参数-这真的是您的意图吗?如果更改了函数的模板参数与其变量参数的类型相同的问题,问题将变得很简单-您为整数对添加了另一个重载,再次使用SFINAE来帮助您。这是实现所需条件的示例方法:

Its a bit of a contrived example and somewhat difficult to make sense of as-is. However, with a basic change its quite easy to add what you require. First its important to note that what you're defining above are not partial specialisations of bar (that would be impossible as you cannot partially specialize a function) but rather overloads. Next, you have a contrived system whereby you have an Enable parameter that has nothing to do with the function parameter - is this really your intention? If you made the change that the template parameter of the function is the same type as its variable parameter, the problem becomes straightforward - you add another overload for integral pairs, again using SFINAE to help you. Here is an example way of achieving what you need:

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

这篇关于用于多种类型的重写成员函数的模板部分专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆